Projects
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.
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
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.
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.
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.
Execution views
System views
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
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.
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.
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.
Canon-Lock Generation Pipeline
Critic failures and human rejections loop back to Reviser — output doesn't advance until both gates pass
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
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.
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.
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.
Single Voice → Multiple Characters
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.
Audio samples coming soon — recordings in progress
Notable decisions
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.
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.
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.