Software Design Document · v1.0
This system is a hybrid learning platform and prompt library for developers and technical creators who use Claude regularly but have never encountered structured AI-assisted build methodology, that solves the absence of a guided, practice-based path from "I use Claude" to "I conduct Claude" through a scrolling homepage that tells the story of boondoggling from first principles, a /dev section of real annotated Gru projects as worked examples, a /tools prompt library where Gru and companion tools can be copied into any Claude Project, and video instruction throughout.
It occupies the space between a methodology explainer (reads but can't practice) and a raw Claude conversation (can practice but teaches nothing).
Success Condition A developer who uses Claude daily arrives, understands the solve-verify asymmetry, copies the Gru system prompt, runs it locally, and completes a real build using the methodology — without needing to ask anyone how.
P1 vs. P3: P3 is primary at the publish gate. P1 is primary for content already live-and-teaching. P2 vs. P1: P2 is primary on format. P1 is primary on outcome. Recommended watch order is surfaced as a suggestion, not a gate.
LEARNER ARRIVES AT / ├── BEAT 1: What is boondoggling? (conductor metaphor, solve-verify asymmetry) ├── BEAT 2: Why does it matter? (five supervisory capacities) ├── BEAT 3: How does it work? → links to /videos for depth ├── BEAT 4: Get the tool → /tools → copy Gru → paste into Claude Project └── BEAT 5: See it in action → /dev worked examples, /videos
Flow Honesty Test If this flow were a command-line prototype — just a README and a copy-paste prompt — would it solve the stated problem? Yes. The site is a surfacing layer, not the core value.
/tools → browse card grid → tool detail page → copy prompt → paste into Claude Project
/dev → browse card grid (category-grouped) → open doc → read SDD in sandboxed iframe
→ optional: navigate to real build (external link)
Submission arrives (email/DM) → Admin creates draft in dashboard → Admin runs Doc Audit Prompt locally (Claude Project) → Decision: publish / return for revision / decline → Published: quality signal set, category assigned, doc visible in /dev
EXTERNAL BOONDOGGLING.AI LEARNER'S LOCAL ENV
──────── ─────────────── ───────────────────
YouTube ←── /videos
Vercel Blob ←── /dev (community uploads) Claude.ai /
←── /blog (cover images) Claude Code
Neon PostgreSQL ←── blog_posts │
←── tools ← Gru system prompt
←── videos (copied from /tools)
←── dev_docs
Vercel ←── deploy on push to main
Single point of failure: Vercel (full site). All other dependencies degrade gracefully. Core teaching path (prompt copy) survives failure of every integration except Vercel.
/public/tools/) + DB-driven (prompt and link tools). Each tool detail page: description, how-to-use instructions, version, copy button, clipboard fallback (<pre> + "Select all"). Character count displayed for prompt-type tools./public/dev/WWW/, /Agents/, /Games/, with /gru/ subfolder in each) + community uploads (Vercel Blob + dev_docs DB table). Card grid groups by category, Gru-badged within each group. Full-viewport sandboxed iframe viewer. Named error component on Blob 404 or missing file.
<meta name="methodology" content="gru"> for Gru badge.youtube-nocookie.com) + Vercel Blob uploads. Search, tag filtering, pagination, pinned videos. Direct YouTube link fallback below every embed.prompt_text, quality_signal, version, published fields. Dev tab adds HTML file upload → Vercel Blob, category (required before publish), methodology, quality_signal, build_url, draft/publish toggle, admin notes field (audit report).| Integration | Purpose | Risk | Failure behavior |
|---|---|---|---|
| Vercel | Deploy + serverless functions | HIGH — sole compute | Previous deployment stays live on build failure |
| Neon PostgreSQL | All DB content | MEDIUM | Blog/videos degrade; /tools artifact + /dev filesystem survive |
| Vercel Blob | Community HTML uploads + blog images | LOW | Named error component; filesystem content unaffected |
| YouTube | Public video embeds | LOW | Direct link fallback; course videos unaffected |
No integration is a hard dependency for the core teaching path (prompt copy). That flow survives failure of every external service except Vercel.
State model: Stateless server, stateless client. No global state store. React useState only, component-scoped. No localStorage.
-- New table
CREATE TABLE IF NOT EXISTS dev_docs (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
title TEXT NOT NULL,
slug TEXT UNIQUE NOT NULL,
description TEXT,
blob_url TEXT NOT NULL,
build_url TEXT,
quality_signal TEXT DEFAULT 'community',
category TEXT, -- 'www' | 'agents' | 'games' — required before publish
methodology TEXT, -- 'gru' | null
submitted_by TEXT, -- display name / handle only — no email
published BOOLEAN DEFAULT false,
published_at TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Extended from Musinique
ALTER TABLE tools ADD COLUMN IF NOT EXISTS prompt_text TEXT;
ALTER TABLE tools ADD COLUMN IF NOT EXISTS quality_signal TEXT DEFAULT 'community';
ALTER TABLE tools ADD COLUMN IF NOT EXISTS version TEXT DEFAULT '1.0';
ALTER TABLE tools ADD COLUMN IF NOT EXISTS published BOOLEAN DEFAULT false;
-- Integrity constraint
ALTER TABLE videos ADD CONSTRAINT video_source_required
CHECK (youtube_id IS NOT NULL OR blob_url IS NOT NULL);
1. CREATE dev_docs → 2. ALTER tools (4 columns) → 3. ALTER dev_docs → 4. ADD video CHECK constraint → 5. Backfill tools (published=true, quality_signal='curated') → 6. RLS policies.
No PII beyond submitted_by (display name only). No regulatory compliance requirements at launch. Privacy policy must note that contributor display names are stored.
| Term | Definition | Reject |
|---|---|---|
| Boondoggling | The practice of conducting Claude through a build by assigning each task to the correct labor, sequencing by dependency, and making every handoff condition explicit | "A workaround" |
| Boondoggle Score | The sequenced, dependency-ordered output of /claude — separating Claude tasks from human tasks with copy-pasteable prompts and handoff conditions | "The build plan" — the SDD is the build plan |
| Gru | The system prompt that instantiates the Gru persona in a Claude Project | "The AI" — Gru is a role, Claude is the AI |
| Tool | A system prompt or HTML artifact in /tools that runs in the learner's local Claude environment | "A feature of the site" |
| Worked Example | A complete, real Gru SDD project hosted in /dev | "A demo" — demos are synthetic |
| Quality Signal | Admin-assigned curation label: Featured or Community | "A rating" |
| Handoff Condition | A specific, testable statement of what must be true about a Claude task's output before the next step begins | "Done criteria" |
| Learner | Anonymous developer/creator acquiring the methodology | "User" — no account at launch |
| Contributor | Practitioner who submits an SDD or tool variant | "User" |
| Entity | Key Fields | Notes |
|---|---|---|
| Tool | tool_type: artifact | link | prompt; prompt_text required when type=prompt; quality_signal: curated | community; version, published | System prompt or HTML artifact in /tools |
| DevDoc | category required before publish; methodology: gru | null; quality_signal: featured | community; submitted_by: display name only | Two sources: filesystem (Nik) and DB (community) |
| BlogPost | Ported from Musinique unchanged | Nik-authored only |
| Video | video_type: youtube | upload; CHECK constraint: at least one of youtube_id or blob_url non-null | YouTube embed or Blob-uploaded course video |
| AdminSession | HMAC-SHA256 signed httpOnly cookie, 7-day expiry | Never client-side |
One context: Content Distribution. No commerce, no identity, no analytics domain at launch.
| Endpoint | Method | Auth | Notes |
|---|---|---|---|
| /api/admin/login | POST | None | Sets admin_session cookie |
| /api/admin/logout | POST | Admin | Clears cookie |
| /api/blog | GET/POST | GET: none, POST: admin | |
| /api/blog/[id] | PATCH/DELETE | Admin | |
| /api/tools | GET/POST | GET: none, POST: admin | prompt_text required for type=prompt |
| /api/tools/[id] | PATCH/DELETE | Admin | |
| /api/dev | GET/POST | GET: none, POST: admin | |
| /api/dev/upload | POST | Admin | Multipart; 5-step validation; Blob then DB |
| /api/dev/[id] | PATCH/DELETE | Admin | DELETE: Blob failure never blocks DB delete |
| /api/videos | GET/POST | GET: none, POST: admin | |
| /api/videos/[id] | PATCH/DELETE | Admin | |
| /api/upload | POST | Admin | Images (5MB) + course videos (500MB) |
All writes are synchronous — 200/201 means DB write completed · All errors return { "error": "string" } — no stack traces in production · PATCH is idempotent — POST is not (duplicate slugs return 409) · Auth validated by middleware before any handler executes · No rate limiting at launch (single admin, read-only public routes)
Five-step server-side validation, run in order: (1) content-type HTML check, (2) ≤500kb size check, (3) HTML signature check (reads first bytes — independent of filename), (4) slug format check (/^[a-z0-9-]+$/ — no slashes), (5) slug uniqueness check in DB. Blob write → DB insert (sequential). Blob failure = clean 500. DB failure after Blob success = orphaned file logged, admin retries safely. Auth is checked before any file processing.
Learner copies Gru prompt: GET /tools → merge filesystem + DB → GET /tools/gru → tool detail page (prompt_text in DOM) → clipboard API → no server call. Survives Neon outage if Gru is filesystem artifact.
Learner views /dev doc: GET /dev → merge filesystem + DB → GET /dev/[slug] → resolve source (filesystem or Blob) → browser loads iframe src → sandboxed render. Blob 404 → named error component.
Admin uploads community doc: POST /api/dev/upload → validate → Blob put() → INSERT dev_docs (draft) → admin runs audit prompt locally → PATCH published=true.
No Chatty Interfaces Every user-facing flow completes in 1–2 API calls. No async event architecture at launch.
| Call | Latency class | Fallback |
|---|---|---|
| Neon SELECT on page load | Medium (100–500ms) | Filesystem content survives |
| Vercel Blob put() | Slow (>500ms) | Clean error, admin retries |
| Vercel Blob GET (iframe) | Fast (<100ms, CDN) | Named error component |
| YouTube iframe | Fast (<100ms, CDN) | Direct link fallback |
| Tag | Count | Percent |
|---|---|---|
| MUST-BUILD | 18 items | 47% — justified; majority are Musinique ports |
| IMPORTANT | 11 items | 29% |
| NICE-TO-HAVE | 7 items | 18% |
| EXPERIMENTAL | 3 items | 8% — user accounts, community form, Substack |
| Item | What it is |
|---|---|
| Homepage scroll arc | Static 5-beat page — no framework complexity |
| Admin dev tab + upload | Most complex admin tab; Blob + DB write sequence |
| /api/dev/upload | 5-step validation, Blob then DB |
| Category/Gru taxonomy | Filesystem directories + meta tag read |
| Iframe sandbox + error | One JSX attribute + one error component |
| Quality signal on cards | One DB field + one CSS class |
| Admin: Doc Audit Prompt | Content entry in /tools — zero code |
Binding record of decisions. Reopening requires a documented reason with a date.
| Item | Reason | Reopen condition |
|---|---|---|
| User accounts | No auth surface needed at launch | v2 |
| Progress tracking | Requires accounts | v2 |
| On-site Claude API | No API proxy; learner runs locally | Permanently excluded unless business model changes |
| Community submission form | Email/DM sufficient at launch | v2 |
| Automated on-site audit | Publish decision is irreducibly human | Permanently excluded |
| Substack integration | Not in content strategy at launch | v2 |
| Course module system | Violates P2 | Permanently excluded |
| Blog/dev comments | Requires moderation infrastructure | v2 |
| Paid content | No commerce context | Separate SDD required |
| Admin analytics dashboard | Vercel Analytics sufficient | v2 |
| Multi-admin / RBAC | Solo operator at launch | v2 |
| Mobile app | Desktop use case | Not planned |
| Global search | High complexity, low launch value | v2 |
| Tool version diff UI | version field sufficient at launch | v2 |
| i18n | English only | Future |
Stack: Next.js 15 (App Router), TypeScript 5, Tailwind CSS, Vercel, Neon PostgreSQL, Vercel Blob. Identical to Musinique.
New: Domain boondoggling.ai — DNS pointed to Vercel before launch.
DATABASE_URL
ADMIN_PASSWORD
BLOB_READ_WRITE_TOKEN
NEXT_PUBLIC_SITE_URL=https://www.boondoggling.ai
NEXT_PUBLIC_GA_ID (optional)
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Unsandboxed community HTML (XSS) | High | High | sandbox attribute on all community iframes — non-negotiable |
| Principle drift during implementation | Medium | High | SDD is the reference; run /g2 before v2 planning |
| Content drought at launch | Medium | High | Three Featured docs + five videos required before launch date is set |
| Blob orphan accumulation | Medium | Low | Log orphaned URLs; monthly manual cleanup; v2 cleanup job |
| Admin publishes without audit | Medium | Medium | UI reminder in dashboard; technical enforcement in v2 |
| Category taxonomy inadequate | Low | Low–Medium | New category = new subdirectory, no code change |
| Gru prompt exceeds Claude Project limit | Low | High | Character count on tool detail page; split prompt as contingency |
14 of 15 questions resolved. One remaining — non-blocking.
youtube_id or blob_url is non-null on every video record. This is addressed in the migration script (step 4 in the run order). Owner: Nik Bear Brown. Status: Non-blocking until migration run.User auth provider · Community submission form + privacy policy · Global search index · Orphaned Blob cleanup job · Audit checkbox enforcement · Fourth /dev category trigger · Substack newsletter integration
| Field | Value |
|---|---|
| Version | 1.0 |
| Date | March 30, 2026 |
| Owner | Nik Bear Brown / Bear Brown & Company / Musinique LLC |
| Produced with | Gru (Ada + Boondoggling layer) |
| Phases completed | V1–V4, S1–S4, D1–D3, P1–P5 |
| Open questions | 1 (OQ-13 — non-blocking) |
| Status | Ready to Govern Implementation |
| Next action | /g2 audit, then /claude Boondoggle Score |