What I've built.

One product on its way to alpha, a few experiments, and the system I used to teach myself how AI actually works. Built to solve real problems — and to learn by doing, not demoing.

Pattern Parsing & Rendering Engine

Alpha

Browser-based system that converts unstructured written stitch instructions into interactive, semantically correct 2D symbol charts. My one real product — in active development, heading to alpha. The hard part isn't the UI — it's the constraint solver underneath.

The problem

Written crochet instructions are unstructured natural language — ambiguous, inconsistent, specific to each designer's shorthand. Converting them to visual charts requires understanding intent, not just parsing syntax. No existing tool handles the full pipeline. Naive grid layouts produce charts that look right but break the actual stitch relationships.

The build

5 subsystems: an AI-powered ontology layer, a constraint-based geometry engine, an interactive Fabric.js canvas, a learning layer that records user corrections, and a Vercel serverless backend proxying Claude. The layout engine places each stitch against its previous-row anchor — not a rigid grid — so stitch relationships are semantically valid, not just visually populated.

What it proves

142 commits. 8,900+ lines of code. 38 stitch symbol types mapped to 25+ geometric primitives. The discipline to recognize a hard layout problem and build a constraint solver instead of shipping a quick approximation. Production CI/CD, fallback safety nets, and a feedback loop that improves first-draft quality over time.

Where it's going

Expanding into a suite of related tools. The parsing and rendering engine is the foundation. Pattern analysis, comparison, and generation tooling is next.

Notable decisions

Domain modeling

Stitch ontology as single source of truth

All stitch geometry is defined in fractions of a slot unit S — no magic numbers anywhere in the codebase. Every renderer, whether browser-side or server-side batch generation, imports the same 811-line ontology. Constraints are named objects with CYC standard references, not comments buried in code. The alternative was hardcoded geometry per renderer, which drifts the moment two renderers disagree.

AI parsing

Two-pass parser with row-level confidence

Pass 1 extracts abbreviations and control flow. Pass 2 fills gaps, resolves anchor positions, and computes exact grid coordinates. Confidence is tracked per row, not globally — a pattern can be "high confidence" on rows 1–5 and "needs review" on 8–10, enabling targeted human correction rather than full re-parse. Separating the passes also means Claude hallucinations in Pass 1 are caught before they corrupt layout geometry in Pass 2.

Rendering

Stateless renderer driven by canonical schema

The SVG renderer decides nothing. A canonical row plan — a typed JSON schema specifying every stitch, column position, row direction, and turning chain status — is fully resolved before the first line is drawn. Same input always produces the same output. This enables batch quality testing across 22 patterns and makes rendering bugs trivially reproducible. The alternative was resolving geometry at draw time, where debugging is guesswork.


Autonomous Execution Engine (IntentOS)

Learning Project

The project I built to actually understand AI — not just use it. An AI-native operating system for work: submit intent in plain language, and it decomposes the goal into a task graph, routes tasks to specialized agents, governs the consequential decisions, and executes to completion. This was my deep end of the pool — the single project that taught me the most about how AI relates to real systems concepts.

Live Output An AI agent system built this playable game. Here it is.
Open full screen ↗

The problem

Most AI tools require constant direction — prompt, review, redirect, repeat. The ceiling on what one person can accomplish stays low. The goal here is different: submit intent once, and the system executes to completion — only surfacing decisions that genuinely require human judgment.

The build

TypeScript, Node.js, Temporal durable workflows for orchestration, PostgreSQL with pgvector for a self-compounding knowledge layer, Next.js 15 command center with DAG visualization. Three-tier governance: autonomous execution, flagged review, and blocking approval — director involvement only at genuinely consequential moments.

What it taught me

14,400+ lines of TypeScript. 107 passing tests. Running on a hardened DigitalOcean VPS. Several real projects executed end-to-end. I started this with no software background and used it to learn orchestration, durable workflows, agent design, and a self-compounding knowledge layer from the ground up. It's what happens when an operator points AI at "how do real systems actually work" and refuses to stop at a demo.

The design philosophy

Not "let Claude do it." Temporal handles concurrency, retries, state durability, and distributed execution. The governance tier system reflects a real operational truth: autonomous is fine until it isn't, and the system knows the difference.

Notable decisions

Governance

Three-tier Temporal signal architecture

Tier 1 executes autonomously. Tier 2 completes and queues for async director review — the graph keeps moving. Tier 3 sends a Temporal signal and genuinely pauses execution until the director responds. Not a flag, not a poll — a durable workflow wait state. The alternative was all-or-nothing blocking, which would stall the entire graph on every consequential step.

Algorithms

Priority-respecting topological sort

Standard Kahn's algorithm picks arbitrary ready nodes. This implementation re-sorts the queue by task priority after every dequeue — not just at the roots — so high-priority research tasks always run before low-priority scaffolding, even when the graph says both are available. The re-sort on every iteration is the detail most implementations skip.

Data layer

Lazy pgvector with deterministic classification

Knowledge artifacts are classified by agent role via a static lookup table — zero LLM cost, zero latency. Vector embeddings are generated lazily on first semantic query, not on insert. The result: a self-compounding knowledge layer that doesn't add overhead to every task execution, only to the retrievals that actually need it.


AI Content Pipeline

Personal Project

A 480-file creative canon with enforced AI voice consistency, custom-built tooling, and a repeatable generation loop. Built to produce consistent, high-volume content across a complex multi-character world — without it drifting into generic output.

Canon-Lock Generation Pipeline

Input Brief character · location · context
System Voice Load 631-line guide injected into context
Claude — Writer First Draft voice-constrained generation
Claude — Critic Voice Check drift · generic phrasing · canon
Claude — Reviser Revision critique applied, voice tightened
Human Canon Gate approve · reject · loop
Output Canon ✓ committed to world bible

Critic failures and human rejections loop back to Reviser — output doesn't advance until both gates pass

480canon files
631 linesvoice guide
15custom tools
149world-bible entries
18game design docs

The problem

High-volume AI content generation drifts. Without strict constraints, every character sounds like the same encyclopedia entry. The project required distinct tonal registers per character type — some guarded and reptilian, some matter-of-fact, some archaic and measured — enforced consistently across hundreds of documents.

The build

A 631-line canonical voice guide is read by every generation task before producing output. 15 custom Python tools manage content cataloging, consistency checking, gap analysis, and stub filling. An Astro-based documentation site surfaces the world bible. A custom constructed language (Tikhora) has a complete glyph set built in FontForge and exported as SVG/PNG pairs.

What it proves

480 files, 65 commits, 149 world-bible entries, 18 game design documents. The discipline to define the problem before generating content, build tools instead of copy-pasting prompts, and enforce quality gates before anything is marked canon. A blueprint for how AI content pipelines should actually be run.

The design philosophy

AI without governance produces noise. The canon-lock workflow — brief, voice check, AI draft, human review, canon — ensures every output earns its place. The same pattern applies anywhere high-volume AI content needs to stay on-voice at scale.

Notable decisions

Voice consistency

631-line canonical guide as injected system context

Every generation task — NPC entries, location descriptions, in-world documents — receives the full voice guide before producing a word. Not a summary, not a reminder: the full specification. A session that never saw prior output still produces content indistinguishable in tone from work written months earlier. The guide is the consistency; everything else is execution.

Quality gate

Canon-lock: AI critique before human review

Brief → AI write → AI critique → AI revise → human review → canon commit. The critic catches voice drift and generic phrasing before the human sees anything. Human judgment is reserved for canon decisions — not proofreading. The result: consistent output at high volume without constant intervention. Nothing enters the world bible without passing both gates.

Infrastructure

15 purpose-built tools instead of managed prompts

Gap analysis, stub filling, consistency checking, content cataloging — each is a Python tool, not a prompt to copy-paste. The tools query existing canon, identify what's missing, and generate targeted briefs. This is the difference between a scalable pipeline and a good prompt library. 480 files produced; the tooling is why it's consistent at that volume.

Sample Output

The pipeline produces output that earns its place in the canon. Examples from the world bible:

Sample canon documents coming soon.


Audio Processing Pipeline

Prototype

Multi-stage audio segmentation and voice transformation pipeline. Segments recorded audio by character and converts voices using ElevenLabs AI. Designed, built, and working in a single session.

Single Voice → Multiple Characters

You record: "Nova says: The signal came from the lower ward. Keth says: Then we move before dawn."
Input Raw Recording one voice, all lines
Parse Cue Detection "Name says:" markers
Split Segmentation audio split by character
Route Voice Map segment → ElevenLabs profile
ElevenLabs Transform per-segment voice conversion
Output Assembled multi-character audio file

What it does

Takes raw recorded audio, segments by speaker and character, and applies AI-powered voice transformation to each segment using the ElevenLabs API. The two-character pipeline handles segmentation, voice assignment, and output assembly end-to-end.

What it proves

Multi-step AI API integration doesn't require a team or a sprint. The pipeline demonstrates what moves fast when the problem is clearly defined and the tools are well-chosen. The same orchestration pattern — ingest, transform, route, assemble — scales to significantly larger multimedia applications.

Before & After

One recording session. One voice. Two distinct characters.

Source — raw recording (one voice, all dialogue)
Output — Nova (ElevenLabs transformed)
Output — Keth (ElevenLabs transformed)

Audio samples coming soon — recordings in progress

Notable decisions

Routing

Cue-based character detection at record time

Routing decisions are embedded in the recording itself — "Nova says:" is a directive, not metadata added later. This eliminates a post-processing classification step entirely. The speaker sets routing intent at the moment of recording; the pipeline just executes it. One session, one voice, complete routing information embedded throughout.

Efficiency

One recording session yields multiple distinct voices

Traditional multi-character audio requires separate recording sessions per voice actor. This pipeline collapses that to a single take: record all dialogue in sequence, cue characters by name, let the pipeline handle the rest. Re-recording a single line means re-recording one segment — not a session per character. Fast iteration at every step.

Scalability

Independent voice profiles per character

Each character maps to an independent ElevenLabs voice profile. Adding a new character requires a new profile and a new cue prefix — no changes to the segmentation or assembly logic. The same pipeline that handles two characters handles ten. The orchestration pattern scales horizontally; the processing code doesn't change.