Long-form story-writer with canon-keeping, sequel-continuity, and self-hosted narration. Database-is-source-of-truth — writer is the tooling.
Big CSS overhaul + page-level adjustments toward a Norse 'museum- quality' aesthetic (not the gaming-rune-bro variant). Restraint + weight + carved typography. Palette shift: - Warmed-black bg (#0a0807) with subtle radial gradient grain - Bone-cream ink (#dbcfb0) replaces the cleaner cream we had - Oxblood accent (#a13a3a) replaces the coffee-shop soft gold - Weathered bronze (#b08443) as secondary accent for headers + meta - Status colors land warmer: sage-moss ok, rust crit, amber-bronze warn Typography: - All caps + 2-3px letter-spacing on display headers (Trajan Pro / Cinzel chain via font-family stack — falls back to weighted serif on machines without the carved face) - Serif prose chain unchanged (Iowan Old Style → Hoefler → Georgia) - Drop cap on the first paragraph of each chapter — small literary flourish in oxblood-bronze Ornament: - Inline SVG knotwork divider (`ornament()` macro) — two flanking circles + an interlace curve between them, used as section breaks. Below the welcome h1; can be sprinkled wherever a visual register break helps. Pages adjusted: - topbar: SKALD wordmark in 4-letterspaced display caps; thin oxblood underline accent; '+ new saga' nav button on the right - sidebar: 'STORIES' → 'SAGAS' (one of cobb's earlier asks); story-row hover gets oxblood left-accent (not gold); per-status pill colors (complete=ok, generating/cleaning/auditing=warn, failed=crit, seed=warn) - story detail: dedicated .story-actions row with '✦ continue this saga' (primary, oxblood-bordered button) and 'generation log →' link - welcome panel: revised copy + ornament + 'begin a new one' link - forms: bordered surface inputs, all-caps display labels, primary- styled submit buttons matching the continue-saga action Mobile (max-width: 800px): - Single-column grid; sidebar lays out above the main panel - Sidebar wrapped in <details open> so it's collapsible (taps the 'Sagas (N)' header). No JS — native HTML semantics. - Chapter-list collapses word-count column on narrow - Char-list goes single-column - All sizes downscale (28px h1, 16px prose, etc) Next pass after I screenshot: tune any contrast/spacing that looks off on the actual render. |
||
|---|---|---|
| docs | ||
| migrations | ||
| seeds/authors | ||
| skald | ||
| skald-core | ||
| vendor/clawdforge | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| compose.yml | ||
| Dockerfile | ||
| entrypoint.sh | ||
| README.md | ||
skald
Long-form story-writer with canon-keeping, sequel continuity, and (future) self-hosted audiobook narration. Database is the source of truth — the writer is the tooling.
Named for the Old Norse poets who composed and memorized kings' sagas across generations.
Status: v0.1 — scaffold
What's wired:
- Rust workspace (
skald-core+skald) - Postgres schema for stories, characters, canon facts, chapters, passages, generation runs, audit findings, tags
- pgvector extension installed for future similarity search
skald import-markdowningests a story file (chapters + bible) into the schemaskald serveexposes/healthand runs migrations on boot- Single-container deploy: postgres + skald in one image
Wired (this commit):
- clawdforge Rust SDK vendored at
vendor/clawdforge/(upstream:Sulkta-Coop/clawdforgeclients/rust/) skald-core::forge— three-pass orchestration shell (gen / cleanup / audit). Prompts are TODO stubs; pipeline plumbing is in place.
Not yet wired:
- Web UI (the inbox + browse + queue surface)
- Prompt templates for the three passes (heavy prompt-engineering work — own session)
skald-core::context— assemble the LLM context blob from DB rows (bible + characters + parent prose summaries + similarity-matched passages)- Embeddings backfill + ivfflat index
- TTS sidecar container + post-render audit chain (see
docs/tts-pipeline.md)
v0.1 smoke
docker compose -p skald up -d
docker exec skald skald import-markdown \
--path /seed/coast-down.md \
--title "The Coast-Down"
curl http://lucy:7780/health
# → { ok: true, db_ok: true, story_count: 1, ... }
Schema (cheat sheet)
stories → meta + status + parent/root for series
characters → real or fictional, story-scoped
canon_facts → setting, mystery, theme, rule, historical_anchor, hook
chapters → full prose body
chapter_summaries → short summaries for cheap context loading
passages → paragraph-level + embedding vector(1536)
generation_runs → every LLM call logged
audit_findings → canon audit output (severity + area)
tags → arbitrary labels
Architecture (v0.1 + the plan)
┌─────────────────────────────────┐
│ skald container │
│ ┌───────────┐ ┌────────────┐ │
│ │ postgres │ │ skald-rust │ │
│ │ pgvector │←─│ axum + cli │ │
│ │ localhost │ │ :7780 │ │
│ └───────────┘ └─────┬──────┘ │
└─────────────────────────┼────────┘
│ HTTP (future)
↓
┌──────────┐
│clawdforge│
└─────┬────┘
↓
opus calls
v1.0+: extract postgres to its own container on db-net. skald
becomes pure stateless rust, connects via DATABASE_URL. Migration
is a connection-string change + a network move; the binary doesn't
care where the DB lives.
License
MIT.