Inspiration

Inspiration is the challenge of completing something beautiful. It often happens that we're unable to bring the words onto the paper when we really want to express something — the eulogy that needs to land, the apology that has to mean it, the love letter that can't pull a punch. Mean It is built for the people who say "I'm not a writer" but desperately need to say something true. It doesn't write for them. It helps them get there themselves — and then it can prove every word is theirs.

What it does

Mean It is a guided writing companion for the moments that matter most. The flow is six steps:

  1. Pick the moment — feeling-first cards (a goodbye, a thank you, an apology) parsed into recipient/occasion/form.
  2. Pick a guide — three creative personas with hand-drawn ink-line mascots and six emotional states each:
    • Wren / The Documentarian — pulls for memory, specifics, a regular Tuesday.
    • Pip / The Poet of Small Things — pulls for the kitchen smell, the small daily kindness.
    • Cassio / The Songwriter — pulls for the unresolved, the line you almost don't say. (Or create your own — see below.)
  3. Interview — live Sonnet 4.6 stream. The guide asks one question at a time, mirrors phrases you wrote back to you, and refuses to draft. The mascot's emotion shifts as the conversation moves. A "phrases held" pane surfaces verbatim substrings the guide is holding onto.
  4. Find the spine — Haiku 4.5 returns 2–3 verbatim phrases from your own answers. You pick the one the piece is built around.
  5. Drafting — split editor on the left, streaming critique cards on the right. Three card kinds: cliché flag, noticing question, verified-yours (line lifted from your interview).
  6. Render — full-bleed letterpress artifact with hover-trace: hover any line, see the question that prompted it and your verbatim answer. A byline meter shows the verified-words percentage; a postmark stamps the artifact.

Five themes (cute → warm → quiet → noir → gothic) modulate both the visuals and the guide's voice. A theme slider in the chrome shifts the whole register live.

The defining mechanism: every word is yours, and we can prove it. The provenance matcher walks each artifact line and decides — exact substring of a user turn, fuzzy match (≤2 edits per word), or unsourced. The byline meter is a real number, not a vibe.

On top: create-your-own-guide via Opus 4.7 (with immutable guardrails re-injected at every step), URL-share for user-authored guides (gzipped + base64url, no backend), modal pack (download / save / share trace / start over / image card), and a reel composer that turns the artifact into a vertical MP4 with photos + your voice.

How we built it

  • Next.js 15 App Router · TypeScript strict · Tailwind · Vitest.
  • Anthropic SDK with three model tiers: Sonnet 4.6 for the interviewer + drafting critique, Haiku 4.5 for spine extraction + ghostwriter audit, Opus 4.7 for the user-authored-guide synthesizer.
  • Edge-style SSE for streamed routes — token deltas, then a phrases_held event with verbatim-validated substrings, then done.
  • Prompt caching on every assembled system prompt via cache_control: { type: 'ephemeral' }. On a five-turn interview that's the difference between $5 and $50.
  • Tool-use for structured output everywhere it matters: record_phrases_held (interview), record_spine (Haiku), record_critique_card (multi-call per draft), record_audit (Haiku flag check), record_guide (Opus synthesizer).
  • Pure deterministic libs where they belong: provenance matching (exact + Levenshtein), share encode/decode (gzip + base64url), guide markdown round-trip, app-state reducer with Zod-validated localStorage persistence.
  • Defense-in-depth on the no-drafting contract — three immutable forbidden rules and three immutable audit_flags are injected at every guide load AND on every share-link import. A tampered share link cannot soften a guardrail by reusing its name with a weaker description.
  • BYO-key UX — users paste an Anthropic key once, it lives in localStorage, gets sent in X-Anthropic-Key per request, and never touches .git/config or server logs. The route falls back to env on missing header. Every Claude-call route also has a stub fallback that returns canned data when no key is available, so the project demos and tests run without burning tokens.
  • 244 passing tests across 36 files, every model call mocked.
  • Three contributors working in parallel (Frex22 = persona, PruthviVKadam = frontend before being cut, d3v07 = audio-video + integration) on a shared persona-core-dev branch with strict file ownership.

Challenges we ran into

  • A force-push wiped out commits early on. Mid-Sprint-1 a teammate rebased the shared branch and dropped four commits worth of work. d3v07 manually cherry-picked the good parts into a clean integration branch (PR #25) to recover. After that we adopted the rule: nobody force-pushes a shared branch, ever.
  • A teammate was cut mid-project. We absorbed PruthviVKadam's frontend lanes — interview chat shell, drafting view, page artifact — into the persona track for Sprints 2-4. That doubled our scope but also gave us tight control over the SSE/critique contracts the UI consumes.
  • Edge runtime ambition vs Node reality. Issue spec called for Edge, but our guide loader reads from disk via node:fs. We shipped Node runtime with documented deviation rather than build-bundle every guide.md at compile time.
  • Mocking streaming APIs in Vitest is fiddly. We built a hoisted-mock pattern with controllable text-trigger functions so SSE event order could be asserted without a real network.
  • The "verbatim" claim has subtle edge cases. Should "her hands" match across two user turns? (No — that lets the model fabricate continuity that wasn't there.) Should fuzzy match be case-insensitive? (No — the spec is strict; case-insensitivity is a knob, not a default.) The matcher is per-turn, post-.trim(), case-sensitive, with a 2-edits-per-word Levenshtein fallback.
  • Multi-turn Opus for guide creation was scoped down to a single all-fields call to fit the clock. The modal compensates by letting the user iterate (close → reopen with edits → re-synthesize).

Accomplishments that we're proud of

  • Provenance that's actually verifiable. The byline meter isn't aspirational — it's the output of a Levenshtein-backed matcher against the user's interview transcript. Hover any line and see the question that prompted it.
  • The no-drafting contract holds even under attack. Three immutable rules + three immutable flags are re-injected at every load. A tampered share link cannot strip them. The guide-create route also runs an attack-pattern check on user input and refuses with 422 if it sees just write the poem for me or similar.
  • Theme as voice modulation, not just paint. Switching from warm to gothic doesn't only swap colors — it changes how Sonnet asks ("most patient with silence... the line you almost don't ask is the one that matters").
  • 244-test gate, no real network in CI. Every Claude call has a mocked test path AND a stub fallback for live dev without a key.
  • Recovery from a force-push regression without losing the design refresh or the cleanup PR.
  • One unified data model. Session, Turn, Guide, Artifact, ProvenanceLine, AuditEntry, CritiqueCard — all from lib/types/session and lib/guides/schema. No parallel types. Everyone imports the same shapes.

What we learned

  • Prompt caching is the difference between $5 and $50 per session. Mark every assembled system prompt cache_control: { type: 'ephemeral' } from day one.
  • Tool use beats prose JSON every time for structured output. The spine extractor is an order of magnitude more reliable since we switched from "return JSON" to a record_spine tool with a strict schema.
  • The ethical claim is most credible when it's verifiable. "Every word is yours" reads as marketing copy until you can hover a line and see the question that pulled it from you.
  • Strict file ownership is the only way three people work on one branch in one day. No shared files except agreed-upon touchpoints, no force-push, PR for every change.
  • Stub fallbacks are a load-bearing pattern. Every Claude-call route falls through to canned data when no key is present. CI never makes real API calls. New contributors clone the repo and npm run dev works without any keys.
  • Cross-lane edits should be rare and explicitly approved. The one redesign that touched a teammate's components was sanctioned in writing first.

What's next for Mean It

  • Real-time provenance scoring during drafting. Currently the byline meter only fires at render — wire it into the drafting pane so users see the percentage update as they type.
  • Promote the audit layer from log-only to blocking. It's already gated on AUDIT_BLOCK=1; once we've calibrated the false-positive rate against real interview transcripts, flip the default.
  • True multi-turn guide creation. Replace the single-shot Opus call with an actual back-and-forth where the persona-author is interviewed the same way the main app interviews users.
  • More forms. v1 ships poem and letter. Eulogy, song lyric, and comic-strip layouts are all in the design package, waiting to be wired.
  • Voice input for the interview. Accessibility win, also better for emotionally heavy moments where typing fights the feeling.
  • Public, curated guide library. Today users either pick one of three built-ins or create their own. A middle tier of community-shared guides would give people a starting point without a blank canvas.
  • Mobile pass on the modal pack and reel composer (currently desktop-tuned).
  • Persistent sessions beyond localStorage so a user can pick up a half-finished eulogy on another device.
  • Real Edge runtime for the streaming routes — bundle the built-in guides at compile time, drop the fs.readFileSync server-only dependency, ship Edge for sub-100ms first-token latency.## Inspiration

Built With

Share this project:

Updates