Initial commit: Beyond the Prompt workshop presentation by Scott Scoble

- Reveal.js presentation on Skills and Subagents pattern
- Nix flake with Caddy-based HTTP server and process-compose orchestration
- ADRs documenting architectural decisions
- Skills for AI implementation guidance
- Full Scott Scoble author attribution in README
This commit is contained in:
Scott Scoble 2026-05-23 18:19:14 -07:00
commit d2da71e53a
33 changed files with 4865 additions and 0 deletions

View file

@ -0,0 +1,89 @@
# ADR 001: Presentation Technology Choice
## Status
Proposed
## Context
We need to create a presentation for "Beyond the Prompt: Lessons from Building with Claude Code" that:
- Can be served via simple HTTP server
- Works well with Nix flake distribution
- Supports code syntax highlighting
- Allows for presenter notes
- Is version-controllable (text-based)
- Can be easily edited and previewed
## Decision
Use **Reveal.js** for the presentation framework.
## Rationale
### Reveal.js Advantages
- **Static HTML/JS/CSS**: Can be served with any simple HTTP server
- **Rich features**: Code highlighting, presenter notes, speaker view, PDF export
- **Nix-friendly**: Available via nixpkgs, no complex build process
- **Offline-capable**: All assets can be bundled
- **Markdown support**: Can write slides in Markdown within HTML
- **Wide adoption**: Well-documented, stable, extensive plugin ecosystem
### Alternatives Considered
**Marp**
- Pros: Pure Markdown, simpler syntax
- Cons: Requires CLI tool, more complex Nix integration, fewer interactive features
- Verdict: Too limiting for technical demos
**Slidev**
- Pros: Vue-based, modern developer experience
- Cons: Requires Node.js build process, heavier Nix integration
- Verdict: Unnecessary complexity for this use case
**Beamer/LaTeX**
- Pros: Academic standard, precise control
- Cons: PDF-only, no interactive demos, steep learning curve
- Verdict: Not suitable for live coding demonstrations
## Implementation Details
### Directory Structure
```
presentation/
├── index.html # Main presentation file
├── css/
│ └── theme/ # Custom themes if needed
├── js/
│ └── reveal.js # Vendored or symlinked
└── assets/
├── images/
└── code-samples/
```
### Serving
- Development: `nix run .#present` → lightweight HTTP server from nixpkgs (e.g., darkhttpd, caddy, or miniserve)
- Production: Static hosting (GitHub Pages, Netlify, etc.)
### Reveal.js Integration in Nix
Use nixpkgs to fetch reveal.js dependencies:
- Option 1: `fetchFromGitHub` to get reveal.js source
- Option 2: Use `buildNpmPackage` if npm-based tooling needed
- Option 3: Direct vendoring with `fetchurl` for specific release
Recommended: **fetchFromGitHub** for reproducibility and ease of updates.
## Consequences
### Positive
- Simple development workflow
- No build step required for basic presentations
- Easy to version control
- Works offline
- Familiar to many developers
### Negative
- Manual Reveal.js updates (if vendored)
- Larger repo size if vendoring full Reveal.js
- Less separation between content and presentation (vs. pure Markdown)
### Mitigation
- Keep Reveal.js minimal (only required files)
- Use Markdown mode for slide content where possible
- Document update process for Reveal.js version bumps

View file

@ -0,0 +1,245 @@
# ADR 002: Nix Flake Architecture
## Status
Proposed
## Context
The project needs a Nix flake that:
- Provides reproducible development environment
- Defines two runnable apps: `present` and `demo`
- Supports multiple platforms (Linux and macOS, both x64 and ARM)
- Minimizes complexity while providing good developer experience
- Follows Nix best practices
## Decision
Implement a multi-platform flake with `forAllSystems` helper, separate apps for presentation and demo, and a comprehensive devShell.
## Architecture
### System Support
```nix
supportedSystems = [
"x86_64-linux"
"aarch64-linux"
"x86_64-darwin"
"aarch64-darwin"
];
```
### Core Outputs
1. **apps.present**
- Type: `app`
- Function: Serve presentation on http://localhost:8000
- Implementation: process-compose orchestrating Caddy server
- Configuration: Nix-generated Caddyfile and process-compose.yaml
2. **apps.demo**
- Type: `app`
- Function: Execute demonstration script
- Implementation: process-compose orchestrating demo processes
- Configuration: Nix-generated process-compose.yaml for demo services
3. **devShells.default**
- Purpose: Development environment with all necessary tools
- Contents: bash, caddy, process-compose, and optional tools (asciinema, etc.)
- Shell hook: Display helpful usage instructions
## Rationale
### Multi-Platform with forAllSystems
**Why**: Developers use various platforms; presentation should work everywhere
**How**: Use `nixpkgs.lib.genAttrs` to generate outputs for all systems
**Alternative**: Single-platform support would exclude contributors
### Separate Apps vs Unified Interface
**Decision**: Two separate apps (`present` and `demo`)
**Why**:
- Clear separation of concerns
- Can run independently
- Better UX (`nix run .#present` is more explicit than `nix run . -- present`)
**Alternative considered**: Single app with subcommands
- Would require argument parsing
- More complex implementation
- Less idiomatic for Nix
### writeScript vs Packages
**Decision**: Use `pkgs.writeScript` for app wrappers
**Why**:
- Simple bash scripts don't need full package machinery
- Reduces boilerplate
- Direct access to flake's `self` reference
- Easier to maintain
**Alternative**: Proper derivations with `stdenv.mkDerivation`
- Overkill for simple wrappers
- More complex to reference source files
### HTTP Server and Process Management
**Decision**: Use **Caddy** for HTTP serving, orchestrated by **process-compose**
**Architecture**:
- **Caddy**: Modern HTTP server with automatic HTTPS, JSON API, config reloading
- **process-compose**: Process orchestrator (alternative to docker-compose for processes)
- **Configuration**: Generated via Nix expressions, no manual config files
**Why Caddy**:
- Configuration as code via Nix
- JSON/Caddyfile generation from Nix expressions
- Powerful features (reverse proxy, file server, API)
- Good developer experience
- Available in nixpkgs
**Why process-compose**:
- Orchestrates multiple services (presentation server, potential demo services)
- YAML config generated from Nix
- Terminal UI for monitoring processes
- Graceful shutdown and dependency management
- Better than ad-hoc bash scripts for multi-process apps
**Configuration Strategy**:
```nix
# Generate Caddyfile
caddyConfig = pkgs.writeText "Caddyfile" ''
:8000 {
root * ${self}/presentation
file_server
encode gzip
}
'';
# Generate process-compose config
processComposeConfig = pkgs.writeText "process-compose.yaml" (builtins.toJSON {
processes = {
presentation = {
command = "${pkgs.caddy}/bin/caddy run --config ${caddyConfig}";
readiness_probe = {
http_get = {
host = "localhost";
port = 8000;
};
};
};
};
});
```
### DevShell Philosophy
**Decision**: Include common tools, comment optional ones
**Why**:
- Balance between "batteries included" and minimalism
- Comments serve as documentation
- Easy to uncomment tools as needed
- Shell hook provides guidance
## Implementation Details
### Flake Structure
```nix
{
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
outputs = { self, nixpkgs }:
let
supportedSystems = [ ... ];
forAllSystems = f: nixpkgs.lib.genAttrs supportedSystems
(system: f system (import nixpkgs { inherit system; }));
in {
apps = forAllSystems (system: pkgs: { ... });
devShells = forAllSystems (system: pkgs: { ... });
};
}
```
### App Implementation Pattern
```nix
present = {
type = "app";
program = "${pkgs.writeScript "present" ''
#!/usr/bin/env bash
exec ${pkgs.process-compose}/bin/process-compose \
up -f ${processComposeConfig}
''}";
};
```
### Configuration File Generation
**Caddy Configuration** (Caddyfile):
```nix
caddyConfig = pkgs.writeText "Caddyfile" ''
:8000 {
root * ${self}/presentation
file_server browse
encode gzip
log {
output stdout
format console
}
}
'';
```
**process-compose Configuration** (YAML via JSON):
```nix
# YAML generation using builtins.toJSON for structured config
processComposeConfig = pkgs.writeText "process-compose.yaml" (
builtins.toJSON {
version = "0.5";
processes = {
caddy = {
command = "${pkgs.caddy}/bin/caddy run --config ${caddyConfig}";
readiness_probe = {
http_get = {
host = "localhost";
port = 8000;
};
};
};
};
}
);
```
### Source File References
- Presentation: `${self}/presentation`
- Demo files: `${self}/demo/`
- Configs are generated, not stored in repo
## Consequences
### Positive
- Reproducible across all major platforms
- Configuration as code (no manual config files)
- Process orchestration with monitoring UI
- Clean separation: presentation vs demo
- Graceful shutdown and process management
- Readiness probes ensure services are up
- All dependencies from nixpkgs
### Negative
- process-compose adds complexity vs simple HTTP server
- Files copied to Nix store (not live-reloaded during development)
- Need to re-run `nix run` after file changes
- YAML generation via JSON (no native YAML in Nix)
### Mitigation
- Complexity justified by better orchestration and monitoring
- For rapid iteration, use devShell with direct commands:
```bash
nix develop
# Then run Caddy directly for live development:
caddy run --config <(echo ':8000 { root * ./presentation; file_server }')
```
- process-compose TUI provides visibility into running services
- JSON→YAML conversion is transparent and well-tested
## Future Considerations
- Add `checks` output for presentation validation (broken links, etc.)
- Add `packages` output for static site generation
- Consider `nix flake init` template for similar presentations
- Add formatter (e.g., alejandra) to devShell
- Explore Caddy admin API for dynamic config updates
- Add hot-reload capability using Caddy's config API
- Consider additional process-compose processes for demo infrastructure

View file

@ -0,0 +1,235 @@
# ADR 003: Demo Implementation Strategy
## Status
Accepted
## Context
The presentation "Beyond the Prompt: Lessons from Building with Claude Code" needs to demonstrate:
- How to use ADRs to guide AI-assisted development
- Effective prompt engineering and task decomposition
- Iterative refinement with architectural constraints
- Real-world workflow patterns with Claude Code
The demo must be:
- Authentic and realistic
- Reproducible for attendees
- Illustrative of actual development patterns
- Version-controlled and sharable
## Decision
**The demo IS the development conversation itself** - specifically, the conversation that builds this presentation system using ADRs to guide Claude Code.
The demo consists of:
1. The ADRs that define the architecture (stored in `docs/adr/`)
2. The conversation transcript showing iterative development
3. The resulting implementation (flake, presentation, etc.)
## Rationale
### Why Conversation-as-Demo
**Authenticity**: Shows real Claude Code usage, not simulation
- Actual tool interactions
- Real decision-making process
- Genuine iterative refinement
- True constraint handling
**Educational Value**: Demonstrates the meta-pattern
- ADRs provide clear boundaries and context
- Constraints drive better design (e.g., "no Python", "use nixpkgs")
- Iterative improvement based on feedback
- Architecture emerges from conversation
**Reproducibility**: Attendees can recreate the pattern
- ADRs are templates for their own projects
- Conversation style is learnable
- Git history shows evolution
- Implementation validates the approach
### Alternative Approaches Considered
**1. Scripted Demo with Simulated Output**
- Pros: Predictable, rehearsable, no live risk
- Cons: Inauthentic, doesn't show real tool, feels staged
- Verdict: Misses the point of "beyond the prompt"
**2. Live Coding Session**
- Pros: Shows real tool, spontaneous
- Cons: Unpredictable, time pressure, can't capture nuance
- Verdict: Too risky for complex architecture decisions
**3. Pre-recorded Video**
- Pros: Perfect execution, editing possible
- Cons: Not interactive, can't adapt to audience questions
- Verdict: Loses conversational flow and learning opportunities
## Implementation Details
### Demo Artifacts
**1. Architecture Decision Records** (`docs/adr/`)
- `001-presentation-technology.md` - Reveal.js choice
- `002-nix-flake-architecture.md` - process-compose + Caddy
- `003-demo-implementation-strategy.md` - This document (meta!)
- `README.md` - ADR index and usage guide
**2. Conversation Transcript** (`docs/demo/`)
Store the actual Claude Code conversation showing:
- Initial requirements gathering
- ADR creation and refinement
- Constraint application ("no Python")
- Architecture evolution (simple → process-compose)
- Decision rationale and tradeoffs
**3. Implementation Artifacts**
- `flake.nix` - The actual working implementation
- `presentation/` - Reveal.js presentation
- Git commits showing progression
### Demo Execution Flow
**Stage 1: Setup** (2 minutes)
- Show empty repo with just README
- Explain the goal: build a presentation system
- Introduce ADRs as the guiding pattern
**Stage 2: ADR Creation** (3 minutes)
- Walk through creating ADR 001 (presentation tech)
- Show how it evaluates alternatives
- Demonstrate decision rationale
**Stage 3: Constraint Refinement** (3 minutes)
- Show conversation applying constraints
- Example: "No Python" → rearchitecture to Caddy
- Demonstrate ADR updates reflecting new decisions
**Stage 4: Implementation Validation** (2 minutes)
- Run `nix run .#present` to prove it works
- Show generated configs (Caddyfile, process-compose.yaml)
- Demonstrate configuration-as-code
**Stage 5: Meta-Reflection** (2 minutes)
- Highlight the pattern: ADRs → Conversation → Implementation
- Show how this approach is reusable
- Provide takeaways for attendees
### Presentation Integration
Embed demo artifacts in the presentation:
```markdown
# Slide: "The Power of ADRs"
- Show ADR 001 side-by-side with implementation
- Highlight how decisions map to code
# Slide: "Iterative Refinement"
- Show conversation excerpt about Python → Caddy
- Display the updated ADR section
- Show the resulting Nix code
# Slide: "Meta Demo"
- Reveal that THIS presentation was built this way
- Show the actual conversation
- Provide GitHub link for full exploration
```
### Nix Integration
The demo app serves the conversation transcript:
```nix
demo = {
type = "app";
program = "${pkgs.writeScript "demo" ''
#!/usr/bin/env bash
# Generate demo config for process-compose
config="${pkgs.writeText "demo-compose.yaml" (builtins.toJSON {
processes = {
conversation-viewer = {
command = "${pkgs.caddy}/bin/caddy file-server --root ${self}/docs/demo --listen :8001";
};
presentation = {
command = "${pkgs.caddy}/bin/caddy file-server --root ${self}/presentation --listen :8000";
};
};
})}"
exec ${pkgs.process-compose}/bin/process-compose up -f "$config"
''}";
};
```
This runs:
- Presentation on `:8000`
- Conversation transcript viewer on `:8001`
## Technical Considerations
### Conversation Capture
- Export Claude Code conversation to markdown
- Format with syntax highlighting
- Preserve timestamps and flow
- Annotate with insights
### Presentation Structure
```
presentation/
├── index.html # Main reveal.js presentation
├── slides/
│ ├── 01-introduction.md
│ ├── 02-the-adr-pattern.md
│ ├── 03-demo-reveal.md # The meta moment
│ └── 04-takeaways.md
└── assets/
├── conversation.md # Embedded transcript excerpts
├── adr-examples/ # ADR screenshots
└── implementation/ # Code snippets
```
### Git History as Artifact
Commit strategy:
```
feat: initial ADRs for presentation architecture
feat: update ADR 002 with process-compose approach
feat: rewrite ADR 003 as conversation-based demo
feat: implement flake based on ADR decisions
docs: add conversation transcript to demo/
```
Git history itself becomes part of the demo narrative.
## Consequences
### Positive
- **Authentic**: Real Claude Code usage, not simulation
- **Educational**: Shows thinking process, not just results
- **Reusable**: Pattern applicable to any project
- **Transparent**: All decisions documented and traceable
- **Self-documenting**: The demo explains itself
- **Meta-awareness**: Presentation about AI development, built with AI
### Negative
- **Complexity**: More sophisticated than simple script
- **Preparation**: Requires curating conversation for clarity
- **Length**: Full conversation may be too detailed for presentation
- **Assumption**: Assumes audience familiarity with ADRs
### Mitigation
- Curate conversation to key decision points
- Provide full transcript as supplementary material
- Include ADR primer in presentation intro
- Offer simplified "getting started" guide for newcomers
## Future Enhancements
- Interactive conversation explorer (search, filter by topic)
- Side-by-side view: ADR ↔ Conversation ↔ Implementation
- Jupyter notebook walking through the process step-by-step
- Template repository: "instant ADR-driven development"
- Video walkthrough with narration over the conversation
- Browser extension to capture Claude Code conversations automatically
## Key Insight
**This ADR is itself part of the demo** - it documents the decision to use the conversation as the demo, demonstrating the recursive, self-referential nature of effective AI-assisted development.
The presentation is its own case study.

80
docs/adr/README.md Normal file
View file

@ -0,0 +1,80 @@
# Architecture Decision Records
This directory contains Architecture Decision Records (ADRs) for the "Beyond the Prompt" presentation project.
## Purpose: Human Documentation
**ADRs are for humans, not AI.** They explain WHY architectural decisions were made, document alternatives considered, and preserve historical context for team members.
**For AI implementation guidance**, see the `/skills` directory. Skills encode HOW to implement the decisions documented in ADRs.
## Index
1. [ADR 001: Presentation Technology Choice](./001-presentation-technology.md) → *Skill: `revealjs-presentation`*
- Decision to use Reveal.js for the presentation
- Rationale, alternatives, and implementation approach
2. [ADR 002: Nix Flake Architecture](./002-nix-flake-architecture.md) → *Skill: `nix-http-server`*
- Multi-platform flake design
- App structure and devShell configuration
- **Key constraint**: No Python dependencies
3. [ADR 003: Demo Implementation Strategy](./003-demo-implementation-strategy.md) → *Skill: `adr-documentation`*
- Conversation-as-demo approach
- Meta-awareness and documentation strategy
## ADR Format
Each ADR follows this structure:
- **Status**: Proposed, Accepted, Deprecated, Superseded
- **Context**: The problem or situation
- **Decision**: What was decided
- **Rationale**: Why this decision was made (including alternatives)
- **Consequences**: Positive, negative, and mitigations
## When to Write an ADR
Create an ADR when making architectural decisions that:
- Affect multiple parts of the system
- Have long-term implications
- Involve trade-offs between alternatives
- Need to be communicated to future contributors
**After writing an ADR**, consider creating a corresponding **Skill** if:
- The decision involves repetitive implementation patterns
- AI should automatically enforce the decision's constraints
- The pattern can be automated with templates/scripts
- You want perfect consistency in implementation
## The ADR + Skill Pattern
```
Make Decision
↓
┌────┴────┐
▼ ▼
ADR Skill
↓ ↓
WHY HOW
Human AI
```
**Example**: ADR 002 documents WHY we chose Caddy (no Python constraint). The `nix-http-server` skill enforces this by NEVER suggesting Python servers.
## Context Efficiency
**Old approach**: Load ADRs into AI context
- 3 ADRs × 1,500 tokens = 4,500 tokens before writing code
- Doesn't scale beyond ~10-20 ADRs
**New approach**: Use Skills for AI, ADRs for humans
- 3 skills × 100 tokens metadata = 300 tokens
- Scales to 100s of patterns
- ADRs remain available for human readers
## Updating ADRs
ADRs are immutable once accepted. To change a decision:
1. Create a new ADR that supersedes the old one
2. Update the old ADR's status to "Superseded by ADR XXX"
3. Update or create corresponding skill to reflect new implementation pattern