Long-form story-writer with canon-keeping, sequel-continuity, and self-hosted narration. Database-is-source-of-truth — writer is the tooling.
Find a file
Kayos 713ba41977 v0.3 step 1: migration 0004 + authors module + web form panels
Migration 0004 — authors + author_revisions + stories.author_id +
stories.author_revision_id + stories.cross_story_memory +
author_corpus. Soul versioning built in from day one per cobb's
locked decisions:
- authors.id immutable identity (slug + display_name + tagline + model)
- author_revisions tracks each soul revision with n monotonic
- Partial unique index 'idx_author_revisions_current' enforces
  exactly one is_current=true per author
- stories.author_revision_id pins to the exact soul used at gen
  time (so 'this was the Orson Black active when chapter 8 was
  written' is always recoverable)
- author_corpus tracks 'authored' + 'read' relationships for the
  v0.3 cross-story memory toggle

skald-core::authors module — CRUD: get_by_slug,
get_with_current_revision, get_current_revision, get_revision,
create_or_get (idempotent), add_revision (transactional, demotes
prior is_current=true), assign_to_story (also touches
author_corpus).

Web v0.1 forms (the second feedback bucket — 'no way to make new
stories', 'no options for sequels'): handlers + form panels +
POST routes for /stories/new and /stories/:id/continue. Both
create a story stub with status='seed'; actual generation will be
fired by 'skald continue' (next commit) walking seed rows.

Norse visual revamp + mobile collapse deferred — vetting full gen
is the priority per cobb's 'green light for v0.3'. Coming back to
the aesthetic after the pipeline works end-to-end against a real
Orson Black-authored Chapter 8 of Coast-Down.
2026-05-13 12:01:29 -07:00
docs docs/authors.md: v0.3 design brainstorm — authors as personas with souls 2026-05-13 11:20:43 -07:00
migrations v0.3 step 1: migration 0004 + authors module + web form panels 2026-05-13 12:01:29 -07:00
skald v0.3 step 1: migration 0004 + authors module + web form panels 2026-05-13 12:01:29 -07:00
skald-core v0.3 step 1: migration 0004 + authors module + web form panels 2026-05-13 12:01:29 -07:00
vendor/clawdforge vendor/clawdforge: refresh SDK — adds SystemMode::Replace for personas 2026-05-13 11:30:13 -07:00
.gitignore scaffold v0.1: postgres+pgvector inside-container, schema, markdown ingest, CLI 2026-05-13 09:04:28 -07:00
Cargo.lock v0.2 scaffold: vendor clawdforge SDK + forge module + Whisper plan 2026-05-13 10:18:56 -07:00
Cargo.toml scaffold v0.1: postgres+pgvector inside-container, schema, markdown ingest, CLI 2026-05-13 09:04:28 -07:00
compose.yml scaffold v0.1: postgres+pgvector inside-container, schema, markdown ingest, CLI 2026-05-13 09:04:28 -07:00
Dockerfile dockerfile: copy vendor/ during cache layer (path-dep needs full crate) 2026-05-13 10:30:58 -07:00
entrypoint.sh scaffold v0.1: postgres+pgvector inside-container, schema, markdown ingest, CLI 2026-05-13 09:04:28 -07:00
README.md v0.2 scaffold: vendor clawdforge SDK + forge module + Whisper plan 2026-05-13 10:18:56 -07:00

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-markdown ingests a story file (chapters + bible) into the schema
  • skald serve exposes /health and 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/clawdforge clients/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.