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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

View file

@ -0,0 +1,283 @@
@import url(https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap);
@import url(https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap);
/* Nix Blue Theme for Remark - Optimized for 100" at 15ft */
body {
font-family: 'Inter', 'Segoe UI', system-ui, sans-serif;
font-size: 38px;
color: #2c3e50;
background: white !important;
}
.remark-notes-preview-area {
display: none;
}
.remark-notes {
height: 100vw;
}
.remark-slide-scaler {
background: white !important;
}
.remark-slide-container {
background: white !important;
}
.remark-slide-content {
background: white !important;
padding: 40px 80px 60px 80px;
}
/* Headings */
h1 {
font-size: 3em;
font-weight: 700;
color: #5277c3;
margin-bottom: 0.5em;
border-bottom: 4px solid #5277c3;
padding-bottom: 0.3em;
}
h2 {
font-size: 2.5em;
font-weight: 700;
color: #5277c3;
margin-bottom: 0.5em;
border-bottom: 3px solid #5277c3;
padding-bottom: 0.2em;
}
h3 {
font-size: 2em;
font-weight: 600;
color: #5277c3;
margin-bottom: 0.4em;
}
/* Text */
p {
line-height: 1.5;
margin: 0.6em 0;
}
/* Lists */
ul, ol {
line-height: 1.6;
margin: 0.8em 0;
}
li {
margin: 0.5em 0;
}
/* Links */
a {
color: #7ebae4;
text-decoration: none;
border-bottom: 2px solid transparent;
transition: border-color 0.2s;
}
a:hover {
border-bottom-color: #5277c3;
}
/* Code */
.remark-code, .remark-inline-code {
font-family: 'Fira Code', 'Monaco', monospace;
}
.remark-inline-code {
background: #f8f9fa;
color: #5277c3;
padding: 0.2em 0.4em;
border-radius: 3px;
font-size: 0.9em;
}
.remark-code {
font-size: 0.75em;
line-height: 1.5;
}
pre {
background: #f8f9fa;
border: 2px solid #e9ecef;
border-radius: 6px;
padding: 1.2em;
margin: 1em 0;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
}
/* Tables */
table {
border-collapse: collapse;
width: 100%;
margin: 1em 0;
font-size: 0.9em;
}
th {
background: #5277c3;
color: white;
padding: 0.6em;
text-align: left;
font-weight: 600;
}
td {
padding: 0.6em;
border-bottom: 1px solid #e9ecef;
}
tr:hover {
background: #f8f9fa;
}
/* Blockquotes */
blockquote {
border-left: 5px solid #5277c3;
padding-left: 1.5em;
margin: 1em 0;
font-style: italic;
color: #666;
}
/* Strong/Bold */
strong {
font-weight: 700;
color: #5277c3;
}
/* Emphasis/Italic */
em {
font-style: italic;
color: #666;
}
/* Slide number */
.remark-slide-number {
font-size: 0.6em;
color: #999;
opacity: 0.6;
}
/* Footnotes */
.footnote {
position: absolute;
bottom: 3em;
font-size: 0.7em;
color: #999;
}
/* Center and middle classes */
.center {
text-align: center;
}
.middle {
vertical-align: middle;
}
/* Two column layout */
.left-column {
width: 48%;
float: left;
}
.right-column {
width: 48%;
float: right;
}
/* Incremental reveal styling */
.remark-visible {
opacity: 1;
}
.remark-invisible {
opacity: 0;
}
/* Syntax highlighting - light theme to match pre blocks */
.hljs {
background: #f8f9fa !important;
color: #2c3e50 !important;
padding: 1.2em !important;
border-radius: 6px;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-literal {
color: #5277c3 !important;
font-weight: 600;
}
.hljs-string,
.hljs-title,
.hljs-section {
color: #0d6efd !important;
}
.hljs-type,
.hljs-class .hljs-title {
color: #198754 !important;
}
.hljs-number,
.hljs-regexp,
.hljs-link {
color: #d63384 !important;
}
.hljs-comment {
color: #6c757d !important;
font-style: italic;
}
/* Checkmarks and X marks */
.remark-slide-content li::before {
content: none;
}
/* Special styling for centered slides */
.remark-slide-content.center.middle {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.remark-slide-content.center.middle h1 {
border-bottom: none;
margin-bottom: 0.3em;
}
/* Image styling */
img {
max-width: 100%;
height: auto;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
/* Presenter notes styling */
.remark-notes {
font-size: 26px;
}
/* Print styles */
@media print {
.remark-slide-scaler {
width: 100% !important;
height: 100% !important;
transform: scale(1) !important;
top: 0 !important;
left: 0 !important;
}
}

View file

@ -0,0 +1,171 @@
/* High Contrast Theme - Bold storytelling with visual pop */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
font-size: 44px;
font-weight: 400;
color: #1a1a1a;
background: white !important;
}
.remark-slide-scaler, .remark-slide-container {
background: white !important;
}
.remark-slide-content {
background: white !important;
padding: 90px 110px;
}
/* Bold headings with color accents */
h1 {
font-size: 4.5em;
font-weight: 700;
color: #0066ff;
margin: 0 0 0.2em 0;
line-height: 1;
letter-spacing: -0.02em;
}
h2 {
font-size: 2.8em;
font-weight: 600;
color: #1a1a1a;
margin: 0.4em 0;
line-height: 1.1;
}
h3 {
font-size: 2em;
font-weight: 600;
color: #666;
margin: 0.5em 0;
}
/* Regular text */
p {
font-weight: 400;
line-height: 1.5;
margin: 1em 0;
}
/* Strong emphasis in accent color */
strong {
font-weight: 700;
color: #0066ff;
}
/* Questions get special treatment */
p:has(strong:first-child) {
font-size: 1.2em;
margin: 1.5em 0;
}
/* Code with accent border */
code {
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
background: #f0f7ff;
color: #0066ff;
padding: 0.15em 0.4em;
border-radius: 3px;
font-size: 0.85em;
font-weight: 600;
}
pre {
background: #1a1a1a;
color: #fff;
padding: 1.8em;
margin: 1.5em 0;
font-size: 0.7em;
line-height: 1.6;
border-radius: 8px;
}
pre code {
background: none;
color: #fff;
padding: 0;
}
/* Lists with accent bullets */
ul, ol {
margin: 1.5em 0;
padding-left: 0;
}
li {
margin: 0.9em 0;
line-height: 1.5;
padding-left: 2em;
position: relative;
}
ul li::before {
content: "▸";
position: absolute;
left: 0;
color: #0066ff;
font-size: 1.2em;
font-weight: 700;
}
/* Blockquotes with accent */
blockquote {
border-left: 8px solid #0066ff;
padding-left: 2em;
margin: 2em 0;
font-size: 1.3em;
color: #333;
font-style: italic;
}
/* Center slides */
.remark-slide-content.center {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
/* Tables */
table {
width: 100%;
margin: 2em 0;
font-size: 0.8em;
border-collapse: collapse;
}
th {
background: #0066ff;
color: white;
padding: 0.8em;
text-align: left;
font-weight: 600;
}
td {
padding: 0.8em;
border-bottom: 1px solid #e0e0e0;
}
tr:hover {
background: #f0f7ff;
}
/* Slide numbers */
.remark-slide-number {
font-size: 0.5em;
color: #ccc;
}
/* Footnotes */
.footnote {
position: absolute;
bottom: 3em;
font-size: 0.6em;
color: #999;
}

View file

@ -0,0 +1,137 @@
/* Minimal Theme - Ultra-clean, maximum focus */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
font-size: 48px;
font-weight: 300;
color: #000;
background: white !important;
}
.remark-slide-scaler, .remark-slide-container {
background: white !important;
}
.remark-slide-content {
background: white !important;
padding: 100px 120px;
}
/* Massive, single-focus headings */
h1 {
font-size: 5em;
font-weight: 600;
color: #000;
margin: 0;
line-height: 1;
letter-spacing: -0.03em;
}
h2 {
font-size: 3em;
font-weight: 300;
color: #666;
margin: 0.3em 0 0 0;
line-height: 1.1;
}
h3 {
font-size: 2em;
font-weight: 400;
color: #999;
margin: 0.5em 0;
}
/* Ultra-light body text */
p {
font-weight: 300;
line-height: 1.7;
margin: 1.5em 0;
max-width: 85%;
}
strong {
font-weight: 600;
color: #000;
}
/* Questions in larger, lighter font */
p strong:first-child {
font-size: 1.2em;
font-weight: 400;
display: block;
margin-bottom: 0.5em;
}
/* Code - monochrome */
code {
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
background: #f5f5f5;
padding: 0.2em 0.4em;
font-size: 0.8em;
color: #000;
}
pre {
background: #f5f5f5;
padding: 2em;
margin: 2em 0;
font-size: 0.65em;
line-height: 1.6;
}
pre code {
background: none;
padding: 0;
}
/* Lists - maximum breathing room */
ul, ol {
margin: 2em 0;
padding: 0;
list-style: none;
}
li {
margin: 1.2em 0;
line-height: 1.6;
padding-left: 2em;
position: relative;
}
li::before {
content: "•";
position: absolute;
left: 0;
font-size: 0.8em;
color: #ccc;
}
/* Center slides - full focus */
.remark-slide-content.center {
display: flex;
flex-direction: column;
justify-content: center;
text-align: center;
}
.remark-slide-content.center p {
max-width: 100%;
}
/* Hide everything except essentials */
.remark-slide-number {
display: none;
}
blockquote {
border: none;
padding: 0;
margin: 2em 0;
font-size: 1.5em;
font-weight: 300;
color: #666;
font-style: normal;
}

View file

@ -0,0 +1,208 @@
/* Modern Storytelling Theme - Clean, bold, narrative-focused */
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Helvetica Neue', Arial, sans-serif;
font-size: 42px;
font-weight: 300;
color: #1a1a1a;
background: white !important;
}
.remark-slide-scaler {
background: white !important;
}
.remark-slide-container {
background: white !important;
}
.remark-slide-content {
background: white !important;
padding: 80px 100px;
}
/* Large impactful headings */
h1 {
font-size: 4em;
font-weight: 700;
color: #000;
margin: 0;
line-height: 1.1;
letter-spacing: -0.02em;
}
h2 {
font-size: 2.5em;
font-weight: 600;
color: #333;
margin: 0.5em 0;
line-height: 1.2;
}
h3 {
font-size: 1.8em;
font-weight: 600;
color: #555;
margin: 0.5em 0;
}
/* Light body text */
p {
font-weight: 300;
line-height: 1.6;
margin: 1em 0;
}
/* Emphasis */
strong {
font-weight: 700;
color: #000;
}
em {
font-style: italic;
color: #666;
}
/* Questions stand out */
.remark-slide-content p:has(strong:contains("Question")),
.remark-slide-content p:has(strong:contains("Quick poll")),
.remark-slide-content p:has(strong:contains("Show of hands")) {
font-size: 1.3em;
font-weight: 600;
color: #2563eb;
margin: 1.5em 0;
}
/* Incremental reveals - subtle */
.remark-visible {
opacity: 1;
}
/* Code - minimal distraction */
code {
font-family: 'SF Mono', Monaco, 'Cascadia Code', 'Courier New', monospace;
background: #f8f9fa;
padding: 0.1em 0.4em;
border-radius: 4px;
font-size: 0.85em;
color: #e63946;
}
pre {
background: #f8f9fa;
border-left: 4px solid #e63946;
padding: 1.5em;
margin: 1.5em 0;
font-size: 0.7em;
line-height: 1.5;
}
pre code {
background: none;
padding: 0;
color: #333;
}
/* Lists - clean and spacious */
ul, ol {
margin: 1.5em 0;
padding-left: 1.5em;
}
li {
margin: 0.8em 0;
line-height: 1.5;
}
/* Remove default bullets, use em dash */
ul li {
list-style: none;
position: relative;
}
ul li::before {
content: "—";
position: absolute;
left: -1.5em;
color: #e63946;
font-weight: 700;
}
/* Blockquotes for emphasis */
blockquote {
border-left: 6px solid #e63946;
padding-left: 2em;
margin: 2em 0;
font-size: 1.2em;
font-weight: 300;
font-style: italic;
color: #555;
}
/* Center content for dramatic effect */
.remark-slide-content.center {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
text-align: center;
}
.remark-slide-content.center h1 {
margin-bottom: 0.3em;
}
.remark-slide-content.center h2 {
font-weight: 400;
color: #666;
}
/* Accent color for key moments */
.accent {
color: #e63946;
font-weight: 700;
}
/* Tables - minimal */
table {
width: 100%;
border-collapse: collapse;
margin: 2em 0;
font-size: 0.8em;
}
th {
background: #f8f9fa;
padding: 0.8em;
text-align: left;
font-weight: 600;
border-bottom: 3px solid #e63946;
}
td {
padding: 0.8em;
border-bottom: 1px solid #e9ecef;
}
/* Slide numbers - subtle */
.remark-slide-number {
font-size: 0.5em;
color: #ccc;
opacity: 0.5;
}
/* Footnotes */
.footnote {
position: absolute;
bottom: 3em;
font-size: 0.6em;
color: #999;
}
/* Speaker notes hidden in presentation */
.remark-notes {
display: none;
}

View file

@ -0,0 +1,315 @@
/* Updated: Centering fix v2 */
/* Theme 1: Terminal Dark (Default) - Hacker aesthetic */
.reveal.theme-terminal {
--r-background-color: #0d1117;
--r-main-font: 'Monaco', 'Courier New', monospace;
--r-heading-font: 'Monaco', 'Courier New', monospace;
--r-main-color: #58a6ff;
--r-heading-color: #8ce99a;
--r-link-color: #79c0ff;
--r-link-color-hover: #a5d6ff;
--r-selection-background-color: #1f6feb;
--r-code-font: 'Monaco', monospace;
}
.reveal.theme-terminal .slides section {
border: 2px solid #30363d;
background: rgba(13, 17, 23, 0.95);
}
.reveal.theme-terminal h1::before,
.reveal.theme-terminal h2::before {
content: '> ';
color: #8ce99a;
}
.reveal.theme-terminal pre {
background: #161b22;
border: 1px solid #30363d;
}
.reveal.theme-terminal code {
background: #161b22;
color: #c9d1d9;
}
/* Theme 2: Nix Blue - Clean and professional */
.reveal.theme-nix {
--r-background-color: #f5f7fa;
--r-main-font: 'Inter', 'Segoe UI', system-ui, sans-serif;
--r-heading-font: 'Inter', 'Segoe UI', system-ui, sans-serif;
--r-main-color: #2c3e50;
--r-heading-color: #5277c3;
--r-link-color: #7ebae4;
--r-link-color-hover: #5277c3;
--r-selection-background-color: #5277c3;
--r-code-font: 'Fira Code', monospace;
}
.reveal.theme-nix {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
}
.reveal.theme-nix .slides section {
background: white;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2);
border-radius: 8px;
}
.reveal.theme-nix h1,
.reveal.theme-nix h2 {
font-weight: 700;
border-bottom: 3px solid #5277c3;
padding-bottom: 0.3em;
}
.reveal.theme-nix pre {
background: #f8f9fa;
border: 2px solid #e9ecef;
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.05);
}
.reveal.theme-nix code {
background: #f8f9fa;
color: #5277c3;
}
/* Theme 3: Solarized Light - Easy on the eyes */
.reveal.theme-solarized {
--r-background-color: #fdf6e3;
--r-main-font: 'Source Sans Pro', sans-serif;
--r-heading-font: 'Source Sans Pro', sans-serif;
--r-main-color: #657b83;
--r-heading-color: #268bd2;
--r-link-color: #2aa198;
--r-link-color-hover: #859900;
--r-selection-background-color: #eee8d5;
--r-code-font: 'Source Code Pro', monospace;
}
.reveal.theme-solarized .slides section {
background: #fdf6e3;
border: 1px solid #eee8d5;
}
.reveal.theme-solarized pre {
background: #eee8d5;
border: 1px solid #d3cbb7;
}
.reveal.theme-solarized code {
background: #eee8d5;
color: #268bd2;
padding: 0.2em 0.4em;
border-radius: 3px;
}
/* Theme 4: Dracula - Vibrant dark mode */
.reveal.theme-dracula {
--r-background-color: #282a36;
--r-main-font: 'Helvetica Neue', Helvetica, sans-serif;
--r-heading-font: 'Helvetica Neue', Helvetica, sans-serif;
--r-main-color: #f8f8f2;
--r-heading-color: #ff79c6;
--r-link-color: #8be9fd;
--r-link-color-hover: #50fa7b;
--r-selection-background-color: #44475a;
--r-code-font: 'Fira Code', monospace;
}
.reveal.theme-dracula {
background: linear-gradient(135deg, #282a36 0%, #44475a 100%);
}
.reveal.theme-dracula h1,
.reveal.theme-dracula h2 {
text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}
.reveal.theme-dracula pre {
background: #1e1f29;
border: 1px solid #44475a;
}
.reveal.theme-dracula code {
background: #44475a;
color: #50fa7b;
padding: 0.2em 0.4em;
border-radius: 3px;
}
/* Theme 5: Nord - Minimalist arctic */
.reveal.theme-nord {
--r-background-color: #2e3440;
--r-main-font: 'Roboto', sans-serif;
--r-heading-font: 'Roboto Slab', serif;
--r-main-color: #eceff4;
--r-heading-color: #88c0d0;
--r-link-color: #81a1c1;
--r-link-color-hover: #5e81ac;
--r-selection-background-color: #4c566a;
--r-code-font: 'JetBrains Mono', monospace;
}
.reveal.theme-nord .slides section {
background: rgba(46, 52, 64, 0.95);
border-left: 4px solid #88c0d0;
}
.reveal.theme-nord pre {
background: #3b4252;
border: 1px solid #4c566a;
}
.reveal.theme-nord code {
background: #3b4252;
color: #8fbcbb;
}
.reveal.theme-nord .fragment.highlight-current-blue.current-fragment {
color: #88c0d0;
}
.reveal.theme-nord strong {
color: #88c0d0;
}
/* Theme selector UI - Floating overlay */
#theme-selector {
position: fixed;
top: 20px;
right: 20px;
z-index: 10000;
background: rgba(0, 0, 0, 0.85);
padding: 12px 18px;
border-radius: 10px;
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4), 0 0 0 1px rgba(255, 255, 255, 0.1);
pointer-events: auto;
backdrop-filter: blur(15px);
-webkit-backdrop-filter: blur(15px);
transition: all 0.3s ease;
isolation: isolate;
}
#theme-selector:hover {
background: rgba(0, 0, 0, 0.95);
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.5), 0 0 0 1px rgba(255, 255, 255, 0.2);
}
/* Ensure theme selector doesn't interfere with presentation */
body {
margin: 0;
padding: 0;
}
.reveal {
pointer-events: auto;
}
#theme-selector label {
color: rgba(255, 255, 255, 0.9);
font-size: 13px;
margin-right: 10px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
font-weight: 500;
letter-spacing: 0.3px;
}
#theme-selector select {
background: rgba(255, 255, 255, 0.95);
border: 1px solid rgba(255, 255, 255, 0.2);
padding: 7px 14px;
border-radius: 6px;
font-size: 13px;
cursor: pointer;
outline: none;
transition: all 0.3s ease;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', system-ui, sans-serif;
font-weight: 500;
}
#theme-selector select:hover {
background: white;
border-color: rgba(88, 166, 255, 0.5);
}
#theme-selector select:focus {
box-shadow: 0 0 0 3px rgba(88, 166, 255, 0.4);
border-color: rgba(88, 166, 255, 0.8);
}
/* Adaptive styling based on presentation theme */
.reveal.has-dark-background ~ #theme-selector {
background: rgba(0, 0, 0, 0.85);
}
.reveal.has-light-background ~ #theme-selector {
background: rgba(0, 0, 0, 0.75);
}
/* Large screen readability - 100" at 15 feet */
.reveal {
font-size: 38px;
}
.reveal h1 {
font-size: 2.5em;
font-weight: 700;
margin-bottom: 0.5em;
}
.reveal h2 {
font-size: 2em;
font-weight: 700;
margin-bottom: 0.5em;
}
.reveal h3 {
font-size: 1.5em;
margin-bottom: 0.4em;
}
.reveal p {
line-height: 1.5;
margin: 0.5em 0;
}
.reveal li {
margin: 0.4em 0;
line-height: 1.5;
}
.reveal ul, .reveal ol {
text-align: left;
}
.reveal pre {
font-size: 0.65em;
}
.reveal code {
font-size: 0.9em;
}
.reveal small {
font-size: 0.7em;
}
/* Responsive adjustments */
@media (max-width: 768px) {
#theme-selector {
top: 10px;
right: 10px;
padding: 8px;
}
#theme-selector label {
display: none;
}
#theme-selector select {
font-size: 12px;
padding: 4px 8px;
}
}

101
presentation/index.html Normal file
View file

@ -0,0 +1,101 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Beyond the Prompt: Lessons from Building with Claude Code by Scott Scoble</title>
<link rel="stylesheet" href="assets/remark-theme.css">
<meta name="author" content="Scott Scoble">
</head>
<body>
<script src="vendor/remark.min.js"></script>
<script>
var slideshow = remark.create({
sourceUrl: 'slides.md',
highlightStyle: 'monokai',
highlightLines: true,
highlightSpans: true,
ratio: '16:9',
navigation: {
scroll: false,
touch: true,
click: false
}
});
// Enhanced presenter mode with separate window control
var presenterWindow = null;
// Listen for 'S' key to open separate presenter window
document.addEventListener('keydown', function(e) {
if (e.key === 's' || e.key === 'S') {
if (!presenterWindow || presenterWindow.closed) {
// Open presenter window
presenterWindow = window.open(
window.location.href + '?presenter=true',
'presenter',
'width=1200,height=800'
);
}
}
});
// Check if this is the presenter window
const urlParams = new URLSearchParams(window.location.search);
const isPresenter = urlParams.get('presenter') === 'true';
if (isPresenter) {
// Enable built-in presenter mode for this window
document.addEventListener('DOMContentLoaded', function() {
slideshow.gotoSlide(slideshow.getCurrentSlideIndex());
});
// Auto-trigger presenter mode
setTimeout(function() {
// Simulate 'p' keypress for presenter mode
var event = new KeyboardEvent('keydown', { key: 'p' });
document.dispatchEvent(event);
}, 500);
}
// Synchronize slides between windows using localStorage
slideshow.on('showSlide', function(slide) {
if (!isPresenter) {
// Main window broadcasts slide changes
localStorage.setItem('current-slide', slide.getSlideIndex());
}
});
// Listen for slide changes from main window (if presenter)
if (isPresenter) {
window.addEventListener('storage', function(e) {
if (e.key === 'current-slide') {
var slideIndex = parseInt(e.newValue);
if (slideshow.getCurrentSlideIndex() !== slideIndex) {
slideshow.gotoSlide(slideIndex);
}
}
});
}
// Display keyboard shortcuts on '?'
document.addEventListener('keydown', function(e) {
if (e.key === '?') {
alert(
'Keyboard Shortcuts:\n\n' +
'Arrow keys / Space: Navigate slides\n' +
'S: Open separate presenter window\n' +
'P: Toggle presenter mode (current window)\n' +
'C: Clone presentation\n' +
'F: Fullscreen\n' +
'?: Show this help'
);
}
});
</script>
<p style="position:fixed;bottom:10px;right:20px;font-size:12px;color:#888;z-index:9999;background:rgba(0,0,0,0.5);padding:4px 10px;border-radius:4px;">
A presentation by <a href="https://scott.scoble.me" style="color:#4ae64a;">Scott Scoble</a>
</p>
</body>
</html>

View file

@ -0,0 +1,204 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Beyond the Prompt: Lessons from Building with Claude Code</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/dist/reveal.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/dist/theme/black.css" id="theme-base">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/plugin/highlight/monokai.css">
<link rel="stylesheet" href="assets/themes.css">
</head>
<body>
<div class="reveal theme-nix">
<div class="slides">
<section>
<h1>Beyond the Prompt</h1>
<h3>Lessons from Building with Claude Code</h3>
<p>
<small>Using ADRs to Guide AI-Assisted Development</small>
</p>
</section>
<section>
<h2>The Challenge</h2>
<p>How do you effectively delegate complex development tasks to an AI assistant?</p>
<ul>
<li class="fragment">Vague prompts → unpredictable results</li>
<li class="fragment">No architectural context → poor decisions</li>
<li class="fragment">Iterative refinement → lost in conversation</li>
</ul>
</section>
<section>
<h2>The Solution: ADRs</h2>
<p><strong>Architecture Decision Records</strong></p>
<ul>
<li class="fragment">Document <em>why</em> decisions were made</li>
<li class="fragment">Provide clear constraints and boundaries</li>
<li class="fragment">Enable iterative refinement with context</li>
<li class="fragment">Create a shared understanding with AI</li>
</ul>
</section>
<section>
<h2>ADR Structure</h2>
<pre><code data-trim data-noescape>
## Status
Proposed | Accepted | Deprecated | Superseded
## Context
The problem or situation requiring a decision
## Decision
What was decided
## Rationale
Why this decision (including alternatives considered)
## Consequences
Positive, negative, and mitigations
</code></pre>
</section>
<section>
<h2>Case Study: This Presentation</h2>
<p class="fragment">This entire presentation system was built using the ADR-driven approach</p>
<p class="fragment"><strong>The demo IS the conversation that built it</strong></p>
</section>
<section>
<h2>ADR 001: Presentation Tech</h2>
<ul>
<li><strong>Decision</strong>: Reveal.js</li>
<li><strong>Why</strong>: Static HTML/JS, no build process, Nix-friendly</li>
<li><strong>Alternatives</strong>: Marp (too limiting), Slidev (complex), Beamer (wrong format)</li>
</ul>
</section>
<section>
<h2>ADR 002: Infrastructure</h2>
<ul>
<li><strong>Decision</strong>: Caddy + process-compose</li>
<li><strong>Why</strong>: Configuration as code, orchestration, monitoring</li>
<li><strong>Constraint Applied</strong>: "No Python" → rearchitecture</li>
</ul>
</section>
<section>
<h2>The Iterative Process</h2>
<ol>
<li class="fragment">Initial ADR: Python HTTP server</li>
<li class="fragment">Constraint: "Python is verboten"</li>
<li class="fragment">Refinement: Evaluated alternatives (darkhttpd, miniserve, caddy)</li>
<li class="fragment">Evolution: Added process-compose for orchestration</li>
<li class="fragment">Result: Better architecture from constraints</li>
</ol>
</section>
<section>
<h2>ADR 003: The Meta Twist</h2>
<p><strong>Decision</strong>: The demo is the conversation itself</p>
<ul>
<li class="fragment">Authentic: Real Claude Code usage</li>
<li class="fragment">Educational: Shows thinking process</li>
<li class="fragment">Reproducible: Pattern is learnable</li>
<li class="fragment">Meta: This ADR documents itself as the demo</li>
</ul>
</section>
<section>
<h2>Key Patterns</h2>
<ul>
<li><strong>Use ADRs for context</strong> - Document decisions, not just code</li>
<li><strong>Apply constraints iteratively</strong> - Better design emerges</li>
<li><strong>Embrace refinement</strong> - First solution rarely perfect</li>
<li><strong>Configuration as code</strong> - Generate, don't write manually</li>
</ul>
</section>
<section>
<h2>The Implementation</h2>
<pre><code class="language-nix" data-trim>
{
apps.present = {
type = "app";
program = writeScript "present" ''
caddy_config=${makeCaddyConfig 8000 presentation}
compose_config=${makeProcessComposeConfig {...}}
exec process-compose up -f "$compose_config"
'';
};
}
</code></pre>
<p class="fragment"><small>Configuration generated from Nix expressions</small></p>
</section>
<section>
<h2>View the Conversation</h2>
<p>The actual development conversation is available at:</p>
<p><a href="http://localhost:8001">http://localhost:8001</a></p>
<p class="fragment"><small>(When running <code>nix run .#demo</code>)</small></p>
</section>
<section>
<h2>Takeaways</h2>
<ol>
<li class="fragment"><strong>ADRs provide boundaries</strong> - Guide AI with context</li>
<li class="fragment"><strong>Constraints improve design</strong> - Limitations force creativity</li>
<li class="fragment"><strong>Conversations are artifacts</strong> - Document the journey</li>
<li class="fragment"><strong>Meta-awareness helps</strong> - Use the tool to understand the tool</li>
</ol>
</section>
<section>
<h2>Try It Yourself</h2>
<pre><code class="language-bash" data-trim>
# Clone the repository
git clone [repo-url]
# Enter development environment
nix develop
# Run the presentation
nix run .#present
# Run the full demo
nix run .#demo
</code></pre>
</section>
<section>
<h2>Resources</h2>
<ul>
<li>ADRs in <code>docs/adr/</code></li>
<li>Conversation transcript in <code>docs/demo/</code></li>
<li>Implementation in <code>flake.nix</code></li>
<li>Git history shows evolution</li>
</ul>
</section>
<section>
<h1>Thank You</h1>
<p>Questions?</p>
<br>
<p><small>This presentation was built with Claude Code using the techniques described</small></p>
</section>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/dist/reveal.js"></script>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/plugin/notes/notes.js"></script>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/plugin/markdown/markdown.js"></script>
<script src="https://cdn.jsdelivr.net/npm/reveal.js@5.0.4/plugin/highlight/highlight.js"></script>
<script>
// Initialize Reveal.js
Reveal.initialize({
hash: true,
plugins: [ RevealMarkdown, RevealHighlight, RevealNotes ],
transition: 'slide',
backgroundTransition: 'fade'
});
</script>
</body>
</html>

234
presentation/print.html Normal file
View file

@ -0,0 +1,234 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Beyond the Prompt - Printable Version</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap');
@import url('https://fonts.googleapis.com/css2?family=Fira+Code:wght@400;500&display=swap');
@page {
size: letter;
margin: 0.75in;
}
body {
font-family: 'Inter', sans-serif;
font-size: 11pt;
line-height: 1.5;
color: #2c3e50;
max-width: 100%;
}
.slide {
page-break-after: always;
margin-bottom: 2em;
border-bottom: 3px solid #5277c3;
padding-bottom: 1em;
}
.slide-header {
background: #5277c3;
color: white;
padding: 0.5em 1em;
margin: -0.75in -0.75in 1em -0.75in;
font-weight: 700;
}
.slide-content h1 {
color: #5277c3;
font-size: 24pt;
margin-top: 0;
border-bottom: 3px solid #5277c3;
padding-bottom: 0.25em;
}
.slide-content h2 {
color: #5277c3;
font-size: 18pt;
margin-top: 0.5em;
}
.slide-content h3 {
color: #5277c3;
font-size: 14pt;
}
.slide-content p {
margin: 0.75em 0;
}
.slide-content ul, .slide-content ol {
margin: 0.75em 0;
padding-left: 2em;
}
.slide-content li {
margin: 0.5em 0;
}
.slide-content code {
font-family: 'Fira Code', monospace;
background: #f8f9fa;
padding: 0.1em 0.3em;
border-radius: 3px;
font-size: 10pt;
}
.slide-content pre {
background: #f8f9fa;
border: 1px solid #e9ecef;
border-radius: 4px;
padding: 1em;
overflow-x: auto;
font-size: 9pt;
}
.slide-content pre code {
background: none;
padding: 0;
}
.speaker-notes {
background: #f8f9fa;
border-left: 2px solid #5277c3;
padding: 0.4em 0.6em;
margin-top: 0.5em;
font-size: 7pt;
font-style: italic;
color: #666;
line-height: 1.3;
}
.speaker-notes-header {
font-weight: 600;
color: #5277c3;
font-style: normal;
margin-bottom: 0.25em;
font-size: 7pt;
}
.speaker-notes p {
margin: 0.25em 0;
font-size: 7pt;
}
.incremental {
margin-left: 2em;
color: #666;
}
.incremental::before {
content: "→ ";
color: #5277c3;
}
blockquote {
border-left: 4px solid #5277c3;
padding-left: 1em;
margin: 1em 0;
font-style: italic;
color: #666;
}
strong {
color: #5277c3;
font-weight: 700;
}
table {
border-collapse: collapse;
width: 100%;
margin: 1em 0;
font-size: 10pt;
}
th {
background: #5277c3;
color: white;
padding: 0.5em;
text-align: left;
}
td {
padding: 0.5em;
border-bottom: 1px solid #e9ecef;
}
@media print {
.slide {
page-break-after: always;
}
.slide-header {
margin: 0;
margin-bottom: 1em;
}
}
</style>
</head>
<body>
<script>
// Fetch and parse the markdown
fetch('slides.md')
.then(response => response.text())
.then(markdown => {
const slides = markdown.split(/\n---\n/);
const container = document.body;
slides.forEach((slide, index) => {
const parts = slide.split(/\n\?\?\?\n/);
const content = parts[0].trim();
const notes = parts[1] ? parts[1].trim() : '';
const slideDiv = document.createElement('div');
slideDiv.className = 'slide';
const header = document.createElement('div');
header.className = 'slide-header';
header.textContent = `Slide ${index + 1}`;
slideDiv.appendChild(header);
const slideContent = document.createElement('div');
slideContent.className = 'slide-content';
// Parse markdown content
let html = content
.replace(/^class: center, middle$/gm, '<div style="text-align: center;">')
.replace(/^--$/gm, '<div class="incremental">')
.replace(/^# (.*$)/gm, '<h1>$1</h1>')
.replace(/^## (.*$)/gm, '<h2>$1</h2>')
.replace(/^### (.*$)/gm, '<h3>$1</h3>')
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/`([^`]+)`/g, '<code>$1</code>')
.replace(/^- (.*$)/gm, '<li>$1</li>')
.replace(/^(\d+)\. (.*$)/gm, '<li>$2</li>')
.replace(/^> (.*$)/gm, '<blockquote>$1</blockquote>')
.replace(/```(\w*)\n([\s\S]*?)```/g, '<pre><code>$2</code></pre>')
.replace(/\n\n/g, '</p><p>');
// Wrap li in ul
html = html.replace(/(<li>.*<\/li>)/s, '<ul>$1</ul>');
slideContent.innerHTML = '<p>' + html + '</p>';
slideDiv.appendChild(slideContent);
if (notes) {
const notesDiv = document.createElement('div');
notesDiv.className = 'speaker-notes';
notesDiv.innerHTML = '<div class="speaker-notes-header">Speaker Notes:</div>' +
notes.replace(/\n\n/g, '</p><p>').replace(/^/, '<p>').replace(/$/, '</p>');
slideDiv.appendChild(notesDiv);
}
container.appendChild(slideDiv);
});
// Auto-print after a short delay
setTimeout(() => {
window.print();
}, 1000);
});
</script>
</body>
</html>

987
presentation/slides.md Normal file
View file

@ -0,0 +1,987 @@
class: center, middle
# Beyond the Prompt
## Lessons from Building with Claude Code
???
⏱️ TIME: 0:00 - 0:30 (0.5 min)
Thanks for coming.
This is a true story from the FLUO project - a behavioral assurance platform for OpenTelemetry. The names haven't been changed because I am not innocent.
---
# Who Am I?
<img src="assets/images/onebrief-careers.png" style="position: absolute; bottom: 60px; left: 100px; width: 240px; height: 240px; object-fit: cover;">
<img src="assets/images/profile.jpg" style="position: absolute; bottom: 60px; right: 100px; width: 340px; height: 340px; border-radius: 50%; object-fit: cover;">
**Scott Scoble**
Senior Software Engineer at Onebrief -- *we're hiring!*
???
⏱️ TIME: 2:00 - 4:00 (2.0 min)
I'm a Sr SWE currently at Onebrief. We're hiring. If you're interested, scan the QR code or go to onebrief dot com. Tell them I sent you when they ask.
--
Building Fluo -- otel traces to behavioral signals
???
I'm building Fluo with Claude Code; a behavioral assurance platform for OpenTelemetry.
--
Building a write only high performance database (no name yet)
???
For Fluo, I'm cooking up a write-only, high performance database built on top of DuckDB and Parquet with some consensus seasoning on top.
---
class: center, middle
<img src="assets/images/scared-diver-diving-into-chaotic-pool--t3chat--1.png" style="position: relative; top: -80px; height: 100vh; object-fit: cover; z-index: 999;" />
???
⏱️ TIME: 4:00 - 4:30 (0.5 min)
Let's dive in.
---
# The Request
"I don't want arbitrary code to run in my JVM."
???
⏱️ TIME: 4:30 - 6:30 (2.0 min)
Over the past few months I've been building FLUO. Users write custom rules using OGNL to match patterns in telemetry traces. But here's the scary part: their code runs in OUR JVM. They could access our database, call our APIs, exfiltrate data.
Remember Log4J?
--
**Quick question**: How many of you have had user code running on your server?
???
How many of you have customer code running on your server?
--
Yeah. That's the problem.
---
# So I Asked Claude Code
"How do we sandbox this?"
???
⏱️ TIME: 6:30 - 8:00 (1.5 min)
I asked Claude how we could have these conditions running inside our JVM through a sandboxing strategy.
--
And that's when I saw Claude auto-compacting our coversation again after only a few minutes.
???
Claude was compacting again; why?
--
**The answer depends on what Claude knows. And space is limited.**
???
Claude could only act on what it knows, but it can't know everything.
---
class: center, middle
# Part 1: The Problem
## Context Window Economics
???
⏱️ TIME: 8:00 - 8:30 (0.5 min)
Let's dive deeper into Claude's context problem.
---
# The Context Window Problem
**Question**: How much documentation does your project have?
???
⏱️ TIME: 8:30 - 11:30 (3.0 min)
How much documentation does your project have? Can it all fit in Claude's context window? How many ADRs?
--
FLUO has 15 ADRs. Plus 10 technical domains. Plus 7 subagent perspectives we need on every decision.
???
FLUO is complex: Nix, Quarkus, React, custom DSL. And we need input from PM, EM, TL, SecOps, SRE, BA, CS on every feature.
--
**If we loaded everything**: 75,000 tokens
???
Traditional approach: load all 15 ADRs. That's 75,000 tokens before writing a single line of code.
Traditional in the sense of the past 6 months or so.
--
Your context window is... gone.
???
The AI can't even start. The context window is full of documentation.
note: ask questions from the group on their documentation excess.
---
# Progressive Disclosure: The Solution
**Level 1**: Metadata (~100 tokens per skill)
```yaml
---
name: security-expert
description: OWASP review, compliance controls
---
```
???
⏱️ TIME: 18:30 - 20:30 (2.0 min)
The solution is called progressive disclosure, and it's built into Anthropic's Skills system.
Level 1: Just metadata. Name and description. About 100 tokens. This is ALWAYS loaded. It's how Claude knows what expertise is available.
---
# Progressive Disclosure: The Solution
**Level 2**: Instructions (~1,000 tokens when triggered)
```markdown
# When to Use
- Code touches authentication
- External API integration
- User input validation needed
```
???
⏱️ TIME: 20:30 - 21:30 (1.0 min)
Level 2: Instructions. The actual "how to" guidance. About 1,000 tokens. Only loads when Claude determines it's relevant to your task.
---
# Progressive Disclosure: The Solution
**Level 3**: Resources (unlimited, on-demand)
```
/skills/security/owasp-checklist.md
/skills/security/threat-models/
```
???
⏱️ TIME: 21:30 - 22:30 (1.0 min)
Level 3: Resources. Detailed checklists, threat models, code examples. Unlimited size. Never loaded into context - accessed on-demand via filesystem.
This three-tier system is why we can have 10 skills, 7 subagents, and still use only 1,700 tokens upfront instead of 75,000.
---
# FLUO's Token Budget
**Traditional (ADRs only)**:
```
75,000 tokens loaded upfront
= Context window exhausted
```
???
⏱️ TIME: 22:30 - 25:30 (3.0 min)
Here's where we started. We loaded all the ADRs upfront and exhausted our token budget. I was compacting every 3 or 4 requests.
--
**With Skills + Subagents**:
```
10 skills × 100 tokens = 1,000 tokens
7 subagents × 100 tokens = 700 tokens
Total: 1,700 tokens metadata
When 2-3 trigger: +3,000 tokens instructions
Total active: ~5,000 tokens
```
???
With Skills and Subagents: 1,700 tokens for all metadata. When 2-3 trigger based on your task, you add about 3,000 more. Total: 5,000 tokens for full guidance.
--
**Result**: 95% token reduction, 97% faster
???
That's a 95% reduction. And because we're not loading massive documents, execution is 97% faster.
But the real win isn't speed. It's preventing waste.
---
# Quick Check
Count your functional docs × 1,500 tokens
--
If >10K, you need this.
--
Now let me show you **why** this matters.
???
⏱️ TIME: 25:30 - 29:30 (4.0 min)
Quick audience check - how big is their documentation? This makes it personal.
If they're over 10K tokens, they have the same problem FLUO had.
Now we go back to the sandboxing story to show how this actually prevented disaster.
---
class: center, middle
# Back to Sandboxing
Remember: user code running in our JVM
???
⏱️ TIME: 29:30 - 32:30 (3.0 min)
We're circling back to the opening problem. The audience remembers the setup.
Now they'll see how the context window solution (Skills + Subagents) saved me from making a terrible decision.
---
class: center, middle
# Part 2: The Pattern
## Building a Dream Team
We're assembling subagents and giving them superpowers (skills)
???
⏱️ TIME: 32:30 - 34:30 (2.0 min)
Now we name the pattern with a relatable metaphor: building a dream team.
Each subagent is like a team member with their own perspective. Skills are their superpowers - the knowledge and constraints they enforce.
The audience has seen the problem (sandboxing), understands the constraint (context windows), and now they'll see the solution: a team of AI agents working together.
Here's how four different subagents each brought their perspective to the table.
---
# The Implementer Speaks
"Use Java SecurityManager. Two weeks, done."
???
⏱️ TIME: 34:30 - 38:30 (4.0 min)
First team member: the implementer. This agent wants to ship fast.
Java SecurityManager. Two-week estimate. Sounds perfect.
--
**Show of hands**: How many would ship this?
???
Ask the audience: would you ship this? Most hands go up. We all want fast solutions.
--
I was ready to.
???
Then reveal: I was ready to. But then another team member spoke up.
Build suspense about what saved us.
---
# The Architect Interrupts
Then the architecture agent spoke up.
???
⏱️ TIME: 38:30 - 43:30 (5.0 min)
The architecture guardian reviews everything against our ADRs. It's relentless.
--
"SecurityManager? **Deprecated in Java 17.**"
???
⏱️ TIME: 38:30 - 43:30 (5.0 min)
It caught something I missed: SecurityManager is deprecated. Removed in Java 21.
???
SecurityManager isn't even available anymore, and it has vulnerabilities.
--
We're using Java 25.
???
Pause here. Let it sink in. The audience gets it: we would have shipped dead code.
The "fast" solution just became the impossible one.
---
# Security Weighs In
"Even if SecurityManager wasn't deprecated..."
"...it's bypassable with reflection."
???
⏱️ TIME: 43:30 - 45:30 (2.0 min)
The security expert is brutal. OWASP compliance is non-negotiable.
SecurityManager has known vulnerabilities. Reflection bypass. No resource limits. A malicious rule could DoS the entire system.
--
"3 out of 10 security rating."
--
**Question**: Would you ship 3/10 security to production?
???
Ask the audience: Would you ship 3/10 security?
The answer is obvious. But here's the thing: I almost did. Because I didn't know.
That's the value of having a security expert review BEFORE writing code.
---
# QA Demands Tests
Testing requirements:
- Attack simulations (reflection bypass)
- Performance regression (<10% overhead)
- Multi-tenant isolation
- Resource exhaustion edge cases
- Concurrency stress tests
--
**Adds 1 week for 95%+ coverage**
???
⏱️ TIME: 45:30 - 46:30 (1.0 min)
The QA expert is fanatical about quality. It doesn't trust any implementation without comprehensive tests.
It defines what testing looks like: Attack simulations trying to bypass each layer. Performance tests to ensure sandboxing doesn't kill throughput. Multi-tenant isolation tests. Resource exhaustion edge cases. Concurrency stress tests.
The implementation specialist is starting to sweat. The product manager hasn't even weighed in yet.
---
# Product Does the Math
**Product Manager evaluates the trade-off**:
--
**Option A: SecurityManager**
```
Timeline: 2 weeks now + 10 weeks rewrite = 12 weeks total
Security: 3/10
Risk: Complete rewrite needed in 6 months
```
???
⏱️ TIME: 46:30 - 51:30 (5.0 min)
Time in AI-speak isn't real; it's relative. Option A looks pretty terrible.
--
**Option B: Capability-based security**
```
Timeline: 6 weeks now + 0 weeks later = 6 weeks total
Security: 10/10
Risk: None (future-proof)
```
???
Half the time and 10/10 security score? Sign me up!
---
# Product Does the Math
**Product Manager evaluates the trade-off**:
> "Ship capability-based security. The 4-week investment now saves 6 weeks later, and we get 10/10 security instead of 3/10."
???
⏱️ TIME: 51:30 - 59:30 (8.0 min)
Finally, the product manager looks at this through the lens of total cost and customer value.
The math is obvious. The 4-week delta upfront saves me 6 weeks of rework. Plus we don't ship a security vulnerability.
Decision made. Ship capability-based security.
---
# The Punchline
So after all that evaluation... how long did it take?
???
⏱️ TIME: 59:30 - 1:06:30 (7.0 min)
So how long did it take this collection of agents to implement the final design?
---
# 3 Days
???
⏱️ TIME: 1:06:30 - 1:11:30 (5.0 min)
Just three days of chats; totalling about 6 hours of my time!
--
The subagents made all the hard decisions. Claude Code just implemented them.
???
The subagents make the hard decisions and explained why. Claude was able to just do the right implementation the first time.
--
They caught:
- Java 17 deprecation
- Security vulnerabilities
- Testing requirements
- Total cost analysis
???
Why so fast? Because all the decisions were made. No backtracking. No "oh wait, this won't work." No rework.
The evaluation took 30 minutes. It prevented 12 weeks of waste.
That's a 2,400x return on time invested.
---
# Next Steps
Start with one skill - pick the constraint AI always violates on your project.
Document it. See what changes.
???
⏱️ TIME: 1:11:30 - 1:15:30 (4.0 min)
Here's your second call to action. Think about your project. What's the one thing AI always gets wrong?
For me, it was suggesting Python dependencies when we wanted pure Nix. For you, it might be "never use eval()", "always validate user input", "follow our naming conventions".
Whatever it is, create a skill for it today. Just one. Put it in a `.skills/` directory. Add YAML frontmatter with a clear description.
Then ask Claude to work on something that would normally violate it. Watch what happens. Claude will follow the skill automatically.
One skill. See how it works. Then expand.
Now let me show you how this pattern prevents waste at scale.
---
class: center, middle
# Part 3: How to Build This
## Specifics, not theory
???
⏱️ TIME: 1:15:30 - 1:17:30 (2.0 min)
We've seen the pattern work. Now let's get specific about how YOU build this for your project.
No more stories. Just concrete steps.
---
# Your Dream Team
**4 Essential Subagents:**
1. **Implementer** - "How do we build this fast?"
2. **Architect** - "Does this fit our principles?"
3. **Security** - "What could go wrong?"
4. **Product** - "Is this worth building?"
--
**Start with 2**: Implementer + one other
???
⏱️ TIME: 1:17:30 - 1:19:30 (2.0 min)
Don't try to build all 4 at once. Start with the implementer (you always need that) plus one other based on your biggest pain point.
If you keep shipping insecure code: add security expert.
If you violate architecture principles: add architect.
If you build features nobody uses: add product manager.
Pick your poison. Start with 2.
---
# Subagent Anatomy
```yaml
---
name: architect
role: Review decisions against ADRs
when: Feature requests, technical decisions
---
# Your Identity
You are an architecture guardian. You enforce our documented principles.
# Your Constraints
- NEVER suggest deprecated technologies
- ALWAYS check compatibility with Java 21
- MUST validate against existing ADRs
# Your Response Format
1. State the architectural principle
2. Explain how the proposal violates/aligns
3. Suggest alternatives if needed
```
???
⏱️ TIME: 1:27:30 - 1:31:30 (4.0 min)
This is what a subagent looks like. Three parts:
1. Metadata: who are you, when do you trigger
2. Identity: your personality and focus
3. Constraints: hard rules you enforce
Keep it under 500 tokens. This loads when needed.
---
# Skill Anatomy
```yaml
---
name: nix-http-server
description: Create HTTP servers for Nix projects
---
# Core Constraint
NEVER suggest Python dependencies.
All deps MUST come from nixpkgs.
# Implementation Pattern
Use Caddy from nixpkgs:
- Generate config with pkgs.writeText
- Use process-compose for orchestration
# Anti-Patterns
❌ python -m http.server
❌ npm http-server (external dependency)
✅ caddy (in nixpkgs)
```
???
Skills are simpler than subagents. They're just knowledge and constraints.
Three sections:
1. Core constraint: the one rule that must never be broken
2. Implementation pattern: how to do it right
3. Anti-patterns: common mistakes to avoid
Under 200 tokens for metadata. Full details load when triggered.
---
# The Evaluation Loop
**Before any feature:**
1. Implementer proposes solution (2 min)
2. Other subagents review (5 min)
3. Conflicts surface early (3 min)
4. Decide: build, redesign, or skip (1 min)
???
This is the specific workflow. Every feature goes through this.
--
**Total: 10 minutes**
**Prevents: days to weeks of waste**
???
Takes 10 minutes. Saves days or weeks.
The key: conflicts surface BEFORE writing code. That's when they're cheap to fix.
After code is written, conflicts are expensive. Sunk cost fallacy kicks in.
---
# Real Numbers from FLUO
**Setup cost**: 3 hours to create 4 subagents + 10 skills
--
**Prevented waste**:
- Sandboxing: 12 weeks (deprecated tech)
- Dark mode: 2 weeks (no customer demand)
- API design: 1 week (security violation)
- Database choice: 3 weeks (wrong scale)
--
**Total saved**: 18 weeks in 3 months
**ROI**: 180x
???
Real numbers. Not hypothetical.
3 hours to set up the dream team and skills.
18 weeks of waste prevented in the first 3 months.
That's 180x return on time invested.
And it compounds. The longer you use it, the more waste you prevent.
---
# FLUO's Results
**Context**: 1,700 tokens (95% reduction)
--
**Waste prevented**:
- Sandboxing: 12 weeks
- Dark mode: 2 weeks
- Dozens of smaller decisions
--
**Speed**: Decisions in minutes, not days
???
Let's look at FLUO's results across the entire project.
Context efficiency: 1,700 tokens for all guidance. 95% reduction. We can add more skills and subagents without hitting context limits.
Waste prevention: The two examples I showed you - sandboxing and dark mode - saved me 14 weeks total. But there were dozens of other decisions where subagents caught issues early or questioned assumptions.
Implementation speed: This might seem counterintuitive, but we shipped faster. Why? Because architectural decisions were made upfront by subagents in minutes, not during implementation through painful refactors. Requirements were clear. Less rework.
The pattern works. Evaluate before execute. Multiple perspectives before any code.
---
# The Pattern
Before building: "Is this worth it?"
Evaluate first. Implement second.
???
Here's your final call to action, and it's the most important one.
Before your next feature request - before you write any code - ask a subagent: "Is this worth building?"
Set up a product-manager subagent. Give it a decision framework like RICE scoring: Reach, Impact, Confidence, Effort.
When a feature request comes in, run the evaluation first. Get the subagent's perspective on customer value, opportunity cost, and strategic fit.
Then decide whether to build it. You'll be shocked how many features fail this test.
Every feature you don't build is time saved for features that matter.
---
# Skills vs Subagents
| Aspect | Skills | Subagents |
|--------|--------|-----------|
| **Purpose** | Technical capabilities | Strategic perspectives |
| **Answer** | "How do we implement X?" | "Should we build X?" |
| **Examples** | nix-http-server, security-owasp | product-manager, tech-lead |
| **Trigger** | Task type (HTTP server needed) | Decision point (evaluate feature) |
| **Output** | Code patterns, anti-patterns | Go/no-go, requirements, risks |
--
**Use both**: Skills for HOW, Subagents for SHOULD
???
Let me clarify the distinction between skills and subagents because they solve different problems.
Skills are technical capabilities. They answer "how do we implement X?" They provide code patterns, anti-patterns, validation scripts.
Subagents are strategic perspectives. They answer "should we build X?" They provide go/no-go decisions, requirements clarification, risk assessment.
Skills trigger based on task type. When you need an HTTP server, the nix-http-server skill triggers.
Subagents trigger at decision points. When evaluating a feature, the product-manager subagent weighs in.
Use both. Skills guide implementation. Subagents guide strategy. Together they prevent waste and ensure quality.
---
# The Three Topics
**1. Context Window Economics**
- Progressive disclosure scales
- 95% token reduction
---
# The Three Topics
**2. Skills + Subagents**
- Skills = HOW to implement
- Subagents = SHOULD we build
---
# The Three Topics
**3. Preventing Waste**
- Evaluate before execute
- Multiple perspectives catch mistakes
???
Let me wrap up by reviewing the three major topics and their CTAs.
Topic 1: Context Window Economics. The problem is finite context. The solution is progressive disclosure. Load metadata for everything, instructions only for relevant skills. CTA: Audit your documentation, migrate to skills if you're over 10K tokens.
Topic 2: Skills + Subagents Pattern. Skills encode technical how. Subagents provide strategic should. Together they guide both implementation and decision-making. CTA: Create one skill for your most-violated constraint today.
Topic 3: Preventing Waste at Scale. The pattern is evaluate before execute. Multiple perspectives catch bad decisions early. CTA: Set up a product-manager subagent and evaluate your next feature before building.
These three topics build on each other. You need context efficiency to have room for multiple perspectives. You need skills and subagents to provide those perspectives. And you use them together to prevent waste.
---
# The Complete Picture
**FluoDSL AST** - what we saved:
???
This entire presentation has been telling one story: the FluoDSL AST decision.
--
**Without subagents**:
- Would have shiped deprecated SecurityManager
- Wasted time trying to make it work
- 3/10 security rating shipped to production
???
Without subagents, we would have shipped Java SecurityManager. Two weeks of work. Looks great. Ships with a 3/10 security rating. Gets completely rewritten 6 months later when we upgrade to Java 21. Total cost: 12 weeks.
--
**With subagents**:
- 30 minutes of evaluation from 4 perspectives
- 3 days (in AI *time*) to implement capability-based security
- 10/10 security rating, future-proof
- Prevented waste of time and tokens
???
With subagents, we spent 30 minutes evaluating from 4 perspectives. Architecture caught the Java 17 deprecation. Security defined the 4-layer model. QA specified comprehensive tests. Product approved the investment to avoid rework.
Implementation took 3 days. We shipped 10/10 security. Future-proof. No rework needed.
---
# The Complete Picture
**The pattern scales**: Apply to every feature, every decision, every architectural choice
???
The pattern scales. Apply it to every feature. Every architectural decision. Every refactor.
Evaluate before execute. Get multiple perspectives before any code.
---
# Questions?
Before I wrap this up, I'd love to hear your questions.
---
# Try It Yourself
**FLUO is open source**: github.com/fluohq/fluo
It's a *work in progress*.
???
FLUO is open source. You can see the exact implementation of this pattern.
--
**What you'll find**:
- `.skills/` - 10 technical skills (Nix, Quarkus, React, DSL, etc.)
- `.subagents/` - 7 strategic perspectives (Product Manager, Engineering Manager, Tech Lead, SecOps, SRE, Business Analyst, Customer Success)
- `docs/adrs/` - Architecture Decision Records (for humans)
- Git history showing Skills + Subagents in action
???
10 skills covering our technical domains. 7 subagents covering strategic perspectives. ADRs documenting the WHY for humans. Git history showing the pattern in action.
---
# Try It Yourself
**FLUO is open source**: github.com/fluohq/fluo
**Start with**:
1. One skill (your most-violated constraint)
2. One subagent (product-manager or tech-lead)
3. One decision (evaluate before building)
???
1. Audit your documentation. If it's over 10K tokens, you have a context window problem. Start migrating to Skills.
2. Create one skill today for the constraint AI always violates. See how it works.
3. Before your next feature, set up a product-manager subagent and evaluate first. Ask "is this worth building?"
These are actionable steps you can take this week. Start small. See results immediately.
Don't try to replicate everything at once. Start small.
One skill for your most-violated constraint. One subagent for decision-making. One feature where you evaluate before building.
See how it works. Expand from there.
You'll never go back to the old way.
---
class: center, middle
# Thank You
<img src="assets/images/wscoble-github.png" style="width: 360px; height: 360px;">
https://github.com/wscoble
.footnote[This presentation built with Skills + Subagents guiding every decision]

94
presentation/vendor/fonts/fonts.css vendored Normal file
View file

@ -0,0 +1,94 @@
@font-face {
font-family: 'Fira Code';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/firacode/v27/uU9eCBsR6Z2vfE9aq3bL0fxyUs4tcw4W_D1sFVc.ttf) format('truetype');
}
@font-face {
font-family: 'IBM Plex Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/ibmplexmono/v20/-F63fjptAgt5VM-kVkqdyU8n5ig.ttf) format('truetype');
}
@font-face {
font-family: 'IBM Plex Sans';
font-style: normal;
font-weight: 300;
font-stretch: normal;
font-display: swap;
src: url(https://fonts.gstatic.com/s/ibmplexsans/v23/zYXGKVElMYYaJe8bpLHnCwDKr932-G7dytD-Dmu1swZSAXcomDVmadSDtFlzAA.ttf) format('truetype');
}
@font-face {
font-family: 'IBM Plex Sans';
font-style: normal;
font-weight: 400;
font-stretch: normal;
font-display: swap;
src: url(https://fonts.gstatic.com/s/ibmplexsans/v23/zYXGKVElMYYaJe8bpLHnCwDKr932-G7dytD-Dmu1swZSAXcomDVmadSD6llzAA.ttf) format('truetype');
}
@font-face {
font-family: 'IBM Plex Sans';
font-style: normal;
font-weight: 600;
font-stretch: normal;
font-display: swap;
src: url(https://fonts.gstatic.com/s/ibmplexsans/v23/zYXGKVElMYYaJe8bpLHnCwDKr932-G7dytD-Dmu1swZSAXcomDVmadSDNF5zAA.ttf) format('truetype');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 300;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuOKfMZg.ttf) format('truetype');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuLyfMZg.ttf) format('truetype');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuGKYMZg.ttf) format('truetype');
}
@font-face {
font-family: 'Inter';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/inter/v20/UcCO3FwrK3iLTeHuS_nVMrMxCp50SjIw2boKoduKmMEVuFuYMZg.ttf) format('truetype');
}
@font-face {
font-family: 'Space Grotesk';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/spacegrotesk/v22/V8mQoQDjQSkFtoMM3T6r8E7mF71Q-gOoraIAEj7oUUsj.ttf) format('truetype');
}
@font-face {
font-family: 'Space Grotesk';
font-style: normal;
font-weight: 600;
font-display: swap;
src: url(https://fonts.gstatic.com/s/spacegrotesk/v22/V8mQoQDjQSkFtoMM3T6r8E7mF71Q-gOoraIAEj42Vksj.ttf) format('truetype');
}
@font-face {
font-family: 'Space Grotesk';
font-style: normal;
font-weight: 700;
font-display: swap;
src: url(https://fonts.gstatic.com/s/spacegrotesk/v22/V8mQoQDjQSkFtoMM3T6r8E7mF71Q-gOoraIAEj4PVksj.ttf) format('truetype');
}
@font-face {
font-family: 'Space Mono';
font-style: normal;
font-weight: 400;
font-display: swap;
src: url(https://fonts.gstatic.com/s/spacemono/v17/i7dPIFZifjKcF5UAWdDRUEY.ttf) format('truetype');
}

18
presentation/vendor/remark.min.js vendored Normal file

File diff suppressed because one or more lines are too long