About
I'm a Forward Deployed Engineer — embedded with enterprise customers, building POCs, translating technical depth into customer outcomes. The job is high-signal, high-context-switching, and relentless. The reading queue never stops growing.
TheCutline is the tool I built to stop feeling guilty about it. Not a summarizer — a triage system. The question it answers isn't "what does this say?" It's "should I even read this?"
Why DSPy, not prompts
The obvious approach is to write a prompt: "You are a helpful assistant. Given this article, classify it as Must Read, Skim, or Bankruptcy." That works on day one. It breaks the moment you swap models, tweak wording, or realize your prompt was implicitly tuned to the last 10 articles you tested it on.
DSPy treats AI behavior as a program, not a string. You define a signature — typed inputs and outputs, a declared intent — and the framework handles prompt construction, output parsing, and retries. The triage signature looks like this:
The reader profile — interests, signal framework, automatic bankruptcy criteria —
lives in a plain profile.md file that's injected at load time.
Change the file, change the behavior. No prompt surgery required.
The feedback loop is the actual product
The triage on day one is fine. The triage after 30 days of feedback is good. That's the bet.
After reading a report you vote on the AI's calls — agree, too low, too high.
Those votes accumulate as labeled examples. Running just optimize passes
them to DSPy's MIPROv2 optimizer, which recompiles the triage signature to better match
your actual preferences — not a generic persona, but the specific pattern of what
you have called Must Read over time.
This is the thing most AI demos skip. The system isn't just callable — it's trainable. And the training loop is just a text file and a justfile recipe.
The stack is deliberately boring
The pipeline runs locally or in GitHub Actions. Reports are JSON files committed to the repo. The frontend is static HTML served by Cloudflare Pages. No database, no backend, no auth, no ops overhead.
The interesting part isn't the infrastructure — it's the triage logic and the feedback loop. The stack is boring by design so that part gets to be the whole story.
What comes next
- → Cloudflare Worker + D1 for a real feedback API — currently votes are manually exported, which is a fine v1 cut but won't last
- → Automated optimize loop — a weekly GHA job that pulls accumulated feedback and recompiles the DSPy program without manual intervention
- → Event-driven processing — handle each link the moment it arrives instead of batching; eliminates the lag between input and signal