78ed1dd2813dbc1093542ef5cd0c7915eb560640
She's submitting work that gets run through an AI detector and wants to pre-check she won't be wrongly flagged. Petal should not answer that with a detector of its own: they misfire badly on non-native English (Stanford 2023 found >50% of TOEFL essays flagged as AI vs. near-zero for native writers), so a percentage aimed at an ESL writer is worse than nothing — it either scares her off her own voice or gives false comfort. So the artifact is provenance, not a verdict. Petal already snapshots every ~3 minutes; this turns that history into a standalone printable report: session breakdown, word-count growth, span, active time. No score is emitted anywhere. Two schema additions back it. preserve_history opts a document out of the 40-snapshot prune cap — right for recovery, wrong for provenance, where you want the whole span including the oldest rows. content_hash/prev_hash chain each snapshot to the one before it, so a history edited or thinned after the fact fails verification. Pruning legitimately severs links, so a link break reports as "gaps" unless preserve_history is on; only a hash that fails against its own contents is unconditionally "broken". The chart's x axis is snapshot order, not wall-clock, and that is the load -bearing decision. On a linear time axis an essay written in three sittings across three days renders as three vertical cliffs separated by empty space — visually identical to text pasted in three chunks, i.e. the report would have argued the opposite of the truth. Breaks are compressed into explicitly labelled gutters instead. TestChartGivesWidthToWriting pins it. The report volunteers its largest single word-count jump and states its own limits: it cannot show who was at the keyboard, or whether typed text was composed or copied in. Overclaiming would be self-defeating — a reader who catches it overstating discounts all of it. HTML rather than server-rendered PDF, as with the other exports: a CJK-safe PDF needs an embedded Unicode font or a headless browser. Print styles are there so the browser's Save as PDF is the handoff path. Claude-Session: https://claude.ai/code/session_016Yr6jELuRc7hyzYLccQKZd
🌸 Petal
A self-hosted, privacy-first writing editor with warm bubbly design, auto-save, and
local-LLM grammar/ESL suggestions. See petal-spec.md for the full
design spec and BUILD_PLAN.md for build progress.
Stack
Go + chi backend · SQLite (modernc, pure Go) · React + Vite + Tiptap + Tailwind v4 frontend ·
local vLLM/Ollama for AI suggestions. Single-binary deployment (frontend embedded via go:embed).
Local development
Two processes during development:
# 1. Backend (serves /api on :8080)
go run ./cmd/server
# 2. Frontend dev server (HMR on :5173, proxies /api → :8080)
cd web && npm install && npm run dev
Open http://localhost:5173 while developing.
Production build (single binary)
cd web && npm run build # emits web/dist (embedded by the Go binary)
cd .. && go build -o petal ./cmd/server
./petal # serves UI + API on :8080
Configuration is via environment variables — copy .env.example to .env.
Status
Early build, multi-session. Auth (Authentik), Copyleaks plagiarism, and Docker/Traefik
deployment are deferred — see BUILD_PLAN.md.
Description
Petal is a self-hosted, privacy-first writing editor for an ESL user. It replaces Grammarly with a warm, bubbly web app that combines Tiptap rich text editing, auto-save cloud storage, and periodic AI-powered grammar/ESL suggestions backed by a local vLLM inference endpoint.
27 MiB
Languages
TypeScript
49.2%
Go
44.1%
Python
3.8%
CSS
1.7%
Shell
0.9%
Other
0.2%