Seed #12

Written by

View this Seed in Compass

01 and 02, in the order they were written — 5 Feb 2026, then 5 Feb 2026
01

I'll implement the hardening checklist for v0, working through homepage UX, receipt page improvements, and API robustness. Let me start by reading the current state of each file. [3 tools called] Now I'll implement each hardening item systematically. ## Task 1: Homepage publish UX hardening [4 tools called] ## Task 2: Receipt page hardening [5 tools called] ## Task 3: API hardening [4 tools called] Perfect! All hardening tasks completed. Here's what was changed: ## Summary of Changes ### Task 1: Homepage Publish UX Hardening ✓ **File: `apps/web/app/page.tsx`** 1. **Character count indicator**: Added real-time character count display above textarea - Shows count as formatted number (e.g., "1,234 characters") - Warning displayed when content exceeds 10,000 characters (doesn't block, just warns) 2. **Parent ID validation**: Added client-side validation before sending request - Validates parent ID is a positive integer when provided - Shows inline error message with amber border if invalid - Clears error when user edits the field - No request sent if validation fails 3. **Form state clearing**: After successful publish, form state is cleared - Both `content` and `parentId` are reset to empty strings - Prevents old draft from appearing when user hits back button ### Task 2: Receipt Page Hardening ✓ **File: `apps/web/app/seed/[id]/page.tsx`** 1. **Historical version banner**: Added clear banner when viewing older versions - Shows "Viewing historical version vX (latest is vY)" with blue styling - Includes clickable link to jump to latest version - Only displays when viewing non-latest version **File: `apps/web/app/seed/[id]/UpdateSeedForm.tsx`** 1. **Disable button when content unchanged**: Button disabled if content matches current version - Compares trimmed content with initial content - Shows "No changes to publish" helper text when disabled - Prevents unnecessary update requests 2. **Persistent success message**: Success message persists after `router.refresh()` - Uses URL search param `?updated=X` to track successful updates - Message displayed via `useEffect` when param present - Survives page refresh/navigation 3. **Verbatim server errors**: Server errors now surfaced exactly as returned - Uses `json?.error || fallback` (changed from `??` to `||`) - Ensures empty strings are also caught and replaced with fallback ### Task 3: API Hardening ✓ **File: `apps/web/app/api/seeds/[id]/update/route.ts`** 1. **Content length validation**: Added 100k character limit - Returns 413 (Payload Too Large) if content exceeds 100,000 characters - Clear error message about the limit 2. **Improved atomicity & error handling**: - Added detailed logging for version insert failures - **Critical error handling**: When `seed_versions` insert succeeds but `seeds` update fails: - Logs as CRITICAL with full context (seed_id, version) - Returns detailed error message with seed_id and version for support - Includes original error message from database - Helps diagnose partial update scenarios ## Files Touched 1. `/apps/web/app/page.tsx` - Homepage UX improvements 2. `/apps/web/app/seed/[id]/page.tsx` - Historical version banner 3. `/apps/web/app/seed/[id]/UpdateSeedForm.tsx` - Update form hardening 4. `/apps/web/app/api/seeds/[id]/update/route.ts` - API validation & error handling ## Lint Status No new errors introduced. Existing TypeScript module resolution warnings for client components are pre-existing and will resolve on dev server restart (all referenced files exist and are correctly implemented). All hardening items from the checklist have been implemented with no scope expansion.

02

Testing

the comparison is made on the words as written

These two versions share little wording, so no marks are shown. Both are dated, both stand, and neither replaces the other.

Testing

Seeds naming this one as parent
Title 1
#guava wrote their own record naming this Seed as its parent. 2026.Named as parent by #guava · declared, not on the public record

Each is the descendant author's own statement of where their idea came from. The author of this Seed was not asked and cannot remove a row, and none of them says they agree with what was written. The second line says only whether that statement is currently on the public record.

Start a Seed from here

A record of your own, written by you, naming this one as its parent. This Seed is unchanged by it.