From 6014d4050161eb28dce5c119a3abaf57dd8ac11d Mon Sep 17 00:00:00 2001 From: ricardosobr Date: Mon, 6 Apr 2026 14:40:31 -0600 Subject: [PATCH] feat: add interactive HTML course that teaches how SpecSafe works Single self-contained HTML file (no dependencies except Google Fonts) with 6 modules covering the full codebase: CLI router, adapter pattern, data flow, safety nets, and architecture. Includes code-to-English translations, group chat animations, step-by-step flow visualizations, quizzes, glossary tooltips, and an interactive architecture diagram. Co-Authored-By: Claude Opus 4.6 (1M context) --- specsafe-course.html | 2222 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2222 insertions(+) create mode 100644 specsafe-course.html diff --git a/specsafe-course.html b/specsafe-course.html new file mode 100644 index 0000000..16e39e6 --- /dev/null +++ b/specsafe-course.html @@ -0,0 +1,2222 @@ + + + + + +How SpecSafe Works — An Interactive Course + + + + + + + + + + + +
+
Interactive Course
+

How SpecSafe Works Under the Hood

+

A visual, interactive guide to understanding the codebase behind the AI-assisted development framework — no coding experience needed.

+ +
+ 6 modules + ~25 min read + TypeScript • CLI tool +
+
+ + + + +
+
+
+ 01 +

What Is SpecSafe?

+

The problem it solves and what happens when you run it for the first time

+
+ +
+ +
+

The Problem: AI Coding Without a Plan

+

Imagine hiring a builder who starts pouring concrete before looking at the blueprints. That's what happens when AI coding tools write code without a structured plan first.

+ +
+
+
?
+

Vague Requirements

+

You say "add authentication" but the AI doesn't know if you mean passwords, social login, or magic links.

+
+
+
!
+

Skipped Tests

+

Code that "looks right" but nobody verified it actually works for all the edge cases.

+
+
+
×
+

Bug Loops

+

AI fixes one bug but creates two more because it doesn't understand the full picture.

+
+
+ +

SpecSafe solves this by enforcing a two-phase workflow: plan thoroughly first, then build with discipline.

+
+ + +
+

Two Phases, One Principle: Think Before You Build

+

Like an architect who draws blueprints before any bricks are laid, SpecSafe splits every feature into a planning phase and a building phase.

+ +
+
+
Phase 1: Planning
+
+
Brainstorm
+
Principles
+
Brief
+
PRD
+
UX
+
Architecture
+
Readiness Check
+
+
+
+
Phase 2: Development
+
+
SPEC — Write the specification
+
TEST — Generate tests first
+
CODE — Write code to pass tests
+
QA — Validate everything
+
COMPLETE — Human approval
+
+
+
+
+ + +
+

Under the Hood: A CLI Tool

+

SpecSafe is a CLI tool you install from npm. It scaffolds your project, installs workflow “skills” for your AI tool, and keeps everything on track.

+ +
+
specsafe init
+
→
+
specsafe install
+
→
+
specsafe update
+
→
+
specsafe doctor
+
+ +
+
💡
+
+ Key Insight: Skills, Not Rules +

SpecSafe doesn't hardcode instructions. It installs "skills" — reusable workflow definitions that teach your AI coding tool how to plan and build. Different AI tools get different skill formats, but the knowledge is the same.

+
+
+
+ + +
+

Your First Look at the Code

+

Here's the entry point — the very first file that runs when you type specsafe in your terminal.

+ +
+
+ CODE +
const program = new Command();
+
+program
+  .name('specsafe')
+  .description('SpecSafe — Skills-first TDD framework')
+  .version(pkg.version);
+
+
+ PLAIN ENGLISH +
+

Create a new command-line program.

+

Give it the name "specsafe" — that's what users type to run it.

+

Add a description that shows when users ask for help.

+

Set the version number by reading it from the project's package.json file.

+
+
+
+
+ + +
+

Check Your Understanding

+ +
+
+

You're building an app and want to add a payment feature. With SpecSafe, what would you do first?

+
+ + + +
+
+
+ +
+

Why does SpecSafe install different "skill" files for different AI tools?

+
+ + + +
+
+
+ + + +
+
+
+
+
+ + + + +
+
+
+ 02 +

Meet the Cast

+

The six main actors inside the codebase and what each one does

+
+ +
+ +
+

Six Characters, One Story

+

Think of SpecSafe like a film crew. Each person has one job, and they coordinate to produce the final product. Here are the main characters.

+ +
+
+
R
+
+ CLI Router index.ts +

The receptionist — hears your command, figures out who should handle it

+
+
+
+
I
+
+ Initializer init.ts +

The set designer — creates the folders, config files, and templates for a new project

+
+
+
+
N
+
+ Installer install.ts +

The translator — takes the master skills and converts them for your specific AI tool

+
+
+
+
A
+
+ Adapters adapters/*.ts +

The localization team — 8 specialists, one for each AI tool's file format

+
+
+
+
D
+
+ Doctor doctor.ts +

The inspector — checks your project is healthy and flags anything broken

+
+
+
+
U
+
+ Updater update.ts +

The maintenance crew — refreshes all tool files when the master skills change

+
+
+
+
+ + +
+

Where They Live

+

Here's how the project is organized on disk. Each actor lives in a specific file.

+ +
+
+ specsafe/ + The whole project +
+
+ generators/src/ + Where the CLI code lives +
+
index.ts CLI Router — parses commands
+
init.ts Initializer — creates new projects
+
install.ts Installer — deploys skills to tools
+
doctor.ts Doctor — health check
+
update.ts Updater — regenerates files
+
registry.ts Adapter lookup table
+
+ adapters/ + One file per AI tool (8 total) +
+
+
+
+ canonical/ + The master copy of all skills, personas, and templates +
+
+
+
+
+ + +
+

How the Router Dispatches Commands

+

When you type specsafe install cursor, the Router figures out you want the install command and sends “cursor” to the Installer. Here's exactly how.

+ +
+
+ CODE +
program
+  .command('install')
+  .description('Install SpecSafe skills for a specific AI tool')
+  .argument('<tool>', 'Tool name (claude-code, cursor, ...)')
+  .action(async (tool: string) => {
+    const { install } = await import('./install.js');
+    await install(tool);
+  });
+
+
+ PLAIN ENGLISH +
+

Register a new command called "install".

+

Describe what it does (this shows in the help screen).

+

Say it requires one argument: the tool name. The angle brackets mean it's required.

+

When someone runs this command, do the following…

+

Load the installer module on the fly (not upfront — saves startup time).

+

Call the install function with whatever tool name the user typed.

+
+
+
+ +
+
💡
+
+ Key Insight: Lazy Loading +

The await import('./install.js') pattern is called dynamic import. It means the install code isn't loaded until someone actually runs the install command. This makes the CLI start faster.

+
+
+
+ + +
+

Check Your Understanding

+ +
+
+

You want to add a new AI tool (say, "windsurf") to SpecSafe. Which files would you need to create or change?

+
+ + + +
+
+
+ +
+

Why does the Router use await import() instead of loading everything at the top of the file?

+
+ + + +
+
+
+ + + +
+
+
+
+
+ + + + +
+
+
+ 03 +

How the Pieces Talk

+

Follow the data as it flows from canonical skills to your AI tool

+
+ +
+ +
+

One Master Copy, Many Translations

+

Imagine a bestselling novel. The author writes one original manuscript. Then professional translators convert it into Spanish, Japanese, French, and more. The story is always the same — only the language changes.

+

SpecSafe works the same way. The canonical/ folder is the original manuscript. Adapters are the translators.

+ +
+
canonical/
Master skills
+
→
+
Claude Code
.claude/skills/
+
Cursor
.cursor/skills/
+
Aider
CONVENTIONS.md
+
…5 more
+
+
+ + +
+

Anatomy of a Skill

+

Each skill is a Markdown file with a metadata header (called frontmatter) at the top. The metadata describes the skill; the body contains the instructions.

+ +
+
+ CODE +
---
+name: specsafe-new
+description: 'Create a new spec with unique ID'
+disable-model-invocation: true
+---
+
+# Create New Spec
+When the user runs /specsafe-new...
+1. Generate a unique SPEC ID
+2. Copy the spec template
+3. Open it for editing
+
+
+ PLAIN ENGLISH +
+

Start of the metadata section (three dashes).

+

This skill is named "specsafe-new".

+

A human-readable description of what it does.

+

The AI can't run this on its own — the user has to trigger it explicitly.

+

End of metadata. Everything below is the actual instruction.

+

 

+

The step-by-step workflow the AI follows when this skill is activated.

+
+
+
+
+ + +
+

The Install Flow: Step by Step

+

Here's exactly what happens when you run specsafe install claude-code. Click "Next Step" to follow the data.

+ +
+
+
+
R
+ CLI Router +
+
+
N
+ Installer +
+
+
L
+ Skill Loader +
+
+
A
+ Adapter +
+
+
D
+ Disk +
+
+
Click "Next Step" to begin
+
+ + + Step 0 / 7 +
+
+
+ + +
+

How Skills Get Parsed

+

The Skill Loader reads each SKILL.md file and splits it into metadata and body. Here's the parser.

+ +
+
+ CODE +
export function parseFrontmatter(content: string) {
+  const normalized = content.replace(/\r\n/g, '\n');
+  const match = normalized.match(
+    /^---\n([\s\S]*?)\n---\n([\s\S]*)$/
+  );
+  if (!match) return { frontmatter: {}, body: content };
+  // ... parse key: value pairs from match[1]
+  return { frontmatter, body: match[2] };
+}
+
+
+ PLAIN ENGLISH +
+

Create a function that takes text content and splits it into parts.

+

First, fix any Windows-style line breaks (different computers use different line endings).

+

Look for the pattern: ---, then metadata, then ---, then the rest. This regex captures both sections.

+

If there's no frontmatter block, just return everything as the body.

+

Otherwise, parse each line of metadata into key-value pairs.

+

Return the metadata and the body separately.

+
+
+
+
+ + +
+

Check Your Understanding

+ +
+
+
+ Scenario +

You update a skill's workflow in the canonical/ folder to fix a bug. But your AI tool is still using the old version. What happened?

+
+
+ + + +
+
+
+ +
+

What does the frontmatter disable-model-invocation: true prevent?

+
+ + + +
+
+
+ + + +
+
+
+
+
+ + + + +
+
+
+ 04 +

The Adapter Pattern

+

How one set of skills becomes files for 8 different AI tools

+
+ +
+ +
+

One Plug, Every Country

+

You know those universal power adapters for international travel? Your laptop charger is the same everywhere — but you need a different plug shape for each country. The electricity (the knowledge) doesn't change. Only the connector does.

+

That's exactly how SpecSafe's adapter pattern works. One interface, eight implementations.

+ +
+
+ CODE +
export interface ToolAdapter {
+  name: string;
+  displayName: string;
+  detect(projectRoot: string): Promise<boolean>;
+  generate(
+    skills: CanonicalSkill[],
+    canonicalDir: string,
+    projectRoot?: string,
+  ): Promise<GeneratedFile[]>;
+}
+
+
+ PLAIN ENGLISH +
+

Define a contract that every adapter must follow:

+

It must have an internal name (like "claude-code").

+

It must have a human-friendly name (like "Claude Code").

+

It must be able to detect if the tool is installed in a project (returns true/false).

+

It must be able to take master skills and produce a list of files in the tool's format.

+
+
+
+
+ + +
+

Watch the Adapters Coordinate

+

Here's how the Installer and Adapters talk to each other when you run specsafe install claude-code.

+ +
+
+
+
+
+ #install-channel +
+
+ + + + + + + +
+ +
+ + + + 0 / 7 messages +
+
+
+ + +
+

Inside the Claude Code Adapter

+

Here's the complete Claude Code adapter — it's one of the simplest. It takes canonical skills and outputs .claude/skills/ files.

+ +
+
+ CODE +
async generate(skills: CanonicalSkill[], canonicalDir: string) {
+  const files: GeneratedFile[] = [];
+
+  for (const skill of skills) {
+    files.push({
+      path: `.claude/skills/${skill.directory}/SKILL.md`,
+      content: reconstructSkillMd(skill),
+    });
+  }
+
+  return files;
+}
+
+
+ PLAIN ENGLISH +
+

This function takes the master skills and the path to canonical files.

+

Start with an empty list of files to create.

+

 

+

For each skill in the master list…

+

Add a file to the list. The path goes into .claude/skills/ with the skill's folder name.

+

The content is the reconstructed SKILL.md (frontmatter + body reassembled).

+

 

+

 

+

Return the complete list of files for the Installer to write to disk.

+
+
+
+
+ + +
+

Eight Adapters, Eight Formats

+

Each adapter speaks its tool's language. Here's what they each produce.

+ +
+
+
C
+

Claude Code

+

Skills in .claude/skills/ + a CLAUDE.md rules file.

+
+
+
Cu
+

Cursor

+

Skills + a .cursor/rules/specsafe.mdc config file.

+
+
+
G
+

Gemini

+

Skills + TOML command definitions.

+
+
+
A
+

Aider

+

A .aider.conf.yml config + a CONVENTIONS.md guide.

+
+
+
Z
+

Zed

+

A .zed/settings.json with embedded conventions.

+
+
+
Co
+

Continue

+

Prompt templates in .continue/prompts/ + a YAML agent config.

+
+
+
+ + +
+

Check Your Understanding

+ +
+
+
+ Scenario +

You're building a new AI coding tool called "WindCode". You want it to work with SpecSafe. What contract must your adapter satisfy?

+
+
+ + + +
+
+
+ + + +
+
+
+
+
+ + + + +
+
+
+ 05 +

Safety Nets

+

How SpecSafe protects your project with security checks and health diagnostics

+
+ +
+ +
+

The Bouncer: Path Security

+

Imagine a nightclub bouncer who checks IDs at the door. No valid ID, no entry. SpecSafe's Installer has a similar guard — before writing any file, it checks that the file path doesn't escape your project folder.

+

This prevents a malicious or buggy skill from writing files to /etc/ or your home directory. It's called path traversal protection.

+ +
+
+ CODE +
const resolvedCwd = resolve(cwd);
+for (const file of files) {
+  const fullPath = resolve(cwd, file.path);
+  if (!fullPath.startsWith(`${resolvedCwd}/`)) {
+    console.error(
+      `Security error: path escapes project`
+    );
+    continue;
+  }
+  // Safe to write the file
+}
+
+
+ PLAIN ENGLISH +
+

Get the full, absolute path to the current project folder.

+

For each file the adapter wants to create…

+

Calculate where this file would actually end up on disk.

+

Does this path start with the project folder? If NOT…

+

Print a security warning and refuse to write the file.

+

Skip this file entirely and move to the next one.

+

 

+

Only if the path is inside the project do we write it.

+
+
+
+
+ + +
+

The Pre-Flight Checklist: Doctor

+

Pilots run a checklist before every takeoff — engines, fuel, instruments. The specsafe doctor command does the same for your project. It checks everything and gives you a clear status report.

+ +
+
+
1
+
+ Config file exists? +

Checks that specsafe.config.json is present and has all required keys

+
+
+
+
2
+
+ Project state exists? +

Verifies PROJECT_STATE.md is present (the spec tracking dashboard)

+
+
+
+
3
+
+ Directory structure intact? +

Confirms specs/active/, specs/completed/, and specs/archive/ all exist

+
+
+
+
4
+
+ Installed tools detected? +

For each tool in your config, checks that the tool's files are actually present

+
+
+
+
+ + +
+

Smart Detection: Finding Your Tools

+

During specsafe init, the Initializer scans your project for known AI tools. It looks for specific marker files — like checking for a doorbell to know if someone lives there.

+ +
+
+ CODE +
const TOOL_DETECT_MAP: Record<string, string> = {
+  'claude-code': '.claude/',
+  'cursor':      '.cursor/',
+  'opencode':    '.opencode/',
+  'gemini':      '.gemini/',
+  'zed':         '.zed/',
+  'aider':       '.aider.conf.yml',
+};
+
+
+ PLAIN ENGLISH +
+

Create a lookup table that maps each tool name to its "marker" — a file or folder that proves the tool is installed.

+

If there's a .claude/ folder, Claude Code is present.

+

If there's a .cursor/ folder, Cursor is present.

+

If there's a .opencode/ folder, OpenCode is present.

+

And so on for each supported tool.

+

 

+

Aider uses a config file instead of a folder.

+
+
+
+ +
+
💡
+
+ Key Insight: Convention Over Configuration +

Instead of asking you to manually list your tools, SpecSafe uses file-system conventions to auto-detect them. This is a common pattern in software — smart defaults that reduce the number of questions you have to answer.

+
+
+
+ + +
+

Check Your Understanding

+ +
+
+
+ Scenario +

A user reports: "I ran specsafe doctor and got a WARNING for tool: cursor with the message 'Tool files not detected'." What's likely wrong?

+
+
+ + + +
+
+
+ +
+

Why does the path security check use startsWith instead of checking for ../ in the path?

+
+ + + +
+
+
+ + + +
+
+
+
+
+ + + + +
+
+
+ 06 +

The Big Picture

+

See the full architecture and understand why it's built this way

+
+ +
+ +
+

The Full Map

+

You've met every character. Now let's zoom out and see how they all connect. Click any component to learn more.

+ +
+
+
+
CLI Layer
+
+
+
+ CLI Router +
+
+
+ Registry +
+
+
+
+
Core Logic
+
+
+
+ Initializer +
+
+
+ Installer +
+
+
+ Doctor +
+
+
+ Updater +
+
+
+
+
Adapter Layer
+
+
+
+ Skill Loader +
+
+
+ 8 Tool Adapters +
+
+
+
+
Data Layer
+
+
+
+ canonical/ +
+
+
+ specsafe.config.json +
+
+
+ PROJECT_STATE.md +
+
+
+
+
Click any component to learn what it does
+
+
+ + +
+

Why It's Built This Way

+

Every architectural decision in SpecSafe exists to solve a real problem. Here are the core design principles.

+ +
+
+
1
+

Single Source of Truth

+

canonical/ is authoritative. Adapters read from it but never write to it. This prevents skills from drifting apart across tools.

+
+
+
2
+

Open for Extension

+

Adding a new tool means creating one adapter file. No other code needs to change — the interface and registry handle the rest.

+
+
+
3
+

Stage Gating

+

Specs must flow SPEC → TEST → CODE → QA → COMPLETE. No skipping. This prevents the "just ship it" impulse that causes bugs.

+
+
+
4
+

Evidence Over Assertions

+

The QA stage requires test evidence, not just "it works trust me." Every requirement must have a passing test to prove it.

+
+
+
+ + +
+

What You Can Do Now

+

After this course, you have the vocabulary and mental model to:

+ +
+
+
✓
+
+ Steer AI better +

You know the two-phase workflow, so you can tell AI "we're in the SPEC stage, don't write code yet"

+
+
+
+
✓
+
+ Debug confidently +

If skills aren't updating, you know to run specsafe update. If files are missing, run specsafe doctor

+
+
+
+
✓
+
+ Extend the system +

You understand the adapter pattern, so you could ask AI to "add a new adapter for WindCode that implements ToolAdapter"

+
+
+
+
✓
+
+ Speak the language +

Frontmatter, adapters, canonical source, path traversal, lazy loading — you own these terms now

+
+
+
+ +
+
🏁
+
+ Course Complete! +

You've traced the full journey from specsafe init to generated skill files, met every actor, and understood the architectural decisions that make it all work. Go build something.

+
+
+
+ + +
+

Final Challenge

+ +
+
+
+ Scenario +

Your team wants to add a new planning step called "Security Review" between Architecture and Readiness. Where would you make this change?

+
+
+ + + +
+
+
+ +
+
+ Scenario +

You discover that a colleague's SpecSafe project has specs jumping straight from SPEC to CODE, skipping the TEST stage. What principle is being violated, and why does it matter?

+
+
+ + + +
+
+
+ + + +
+
+
+
+
+ + + + +