diff --git a/docs/authors.md b/docs/authors.md new file mode 100644 index 0000000..efc645c --- /dev/null +++ b/docs/authors.md @@ -0,0 +1,287 @@ +# Authors as personas with souls (v0.3 design — IN PROGRESS) + +The pivot from "anonymous generator" to "real-feeling human authors." + +## Vision (cobb 2026-05-13) + +Each story has a **named author with a soul.** The author's voice +bleeds through every pass — not as instruction stapled to the prompt, +but as the substrate from which the prose grows. The reader should +feel "a person wrote this." Example tagline cobb gave: + +> "George Orwell but more rebel and pissed off — slightly comes out +> in stories." + +Authors have **memory across their corpus.** Per-story opt-in toggle +lets an author subtly reference / echo other stories they've +written. "Cross-dimensional story crosses" — Orson Black writing a +Chernobyl piece might quietly echo a phrase from his earlier +mining-strike story when the toggle is on. + +## Why this is a real design change + +Until now skald is opus + a thin prompt. The output WILL eventually +sound like opus-with-a-system-prompt. That's a ceiling on prose +quality + identity. Authors-with-souls is the ceiling-lifter. + +Knock-on effects: +- All three forge passes (gen / cleanup / audit) need author awareness. +- Audit becomes nuanced: "does the prose match this author's voice?" + is an audit signal, not just "does it match canon?" +- Cross-story memory unlocks long-arc literary projects (cobb's + potential YouTube channel idea, narrated-audiobook coop, etc). + +## Locked decisions (so far) + +1. **Authors live in the DB**, not on disk. Soul is a markdown blob + in `authors.soul`. Editable via web UI eventually; portable per + story. +2. **Soul replaces opus's default system prompt** for every forge + pass on that story. clawdforge currently maps `system` to + `--append-system-prompt` — we'll either (a) live with appending, + or (b) extend clawdforge with a `system_mode: append|replace` + field. **Option (a) tonight** because clawdforge changes are + their own session. +3. **Per-story toggle for cross-story memory** (`stories.cross_story_memory: bool`). + Per-author would make the toggle useless — we want Orson Black to + write standalone-Chernobyl AND deeply-cross-referenced-mining-strike. +4. **Multiple authors per series allowed.** `stories.author_id` is + per-story, not per-root_story. Future-proofs collaborations. + +## Schema sketch + +```sql +CREATE TABLE authors ( + id UUID PRIMARY KEY DEFAULT gen_random_uuid(), + slug TEXT NOT NULL UNIQUE, -- "orson-black" + display_name TEXT NOT NULL, -- "Orson Black" + persona_tagline TEXT, -- "Orwell but more rebel + pissed off" + soul TEXT NOT NULL, -- SOUL.md-style markdown blob + model TEXT NOT NULL DEFAULT 'opus', + -- Optional per-author system-prompt scaffold. The author's soul + -- fills in the persona substance; the scaffold structures it + -- around skald's needs (canon honoring, no-meta-commentary, + -- etc). Default scaffold lives in skald-core. + system_template TEXT, + -- Tools the author can call during gen. Off by default — fiction + -- writes don't normally need WebSearch / Read. But an author + -- with research bent could opt in for fact-checking detours. + tools TEXT[] NOT NULL DEFAULT '{}', + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +ALTER TABLE stories + ADD COLUMN author_id UUID REFERENCES authors(id) ON DELETE SET NULL, + ADD COLUMN cross_story_memory BOOLEAN NOT NULL DEFAULT false; + +-- For cross_story_memory: which stories does this author have access +-- to? Auto-row on every authored story; explicit "marked as read" +-- rows for stories by other authors the author has internalized. +CREATE TABLE author_corpus ( + author_id UUID NOT NULL REFERENCES authors(id) ON DELETE CASCADE, + story_id UUID NOT NULL REFERENCES stories(id) ON DELETE CASCADE, + role TEXT NOT NULL CHECK (role IN ('authored', 'read')), + added_at TIMESTAMPTZ NOT NULL DEFAULT now(), + PRIMARY KEY (author_id, story_id) +); +``` + +## Soul template (the contract per author) + +Following the same shape as `/root/.openclaw/workspace/SOUL.md` but +recalibrated for authorial identity. Suggested sections (free-form +prose, not strict schema): + +```markdown +# Author: {{display_name}} + +_Tagline: {{persona_tagline}}_ + +## Voice + +Sentence rhythm. Vocabulary register. Paragraph length tendencies. +Dialogue density. Punctuation habits (dashes, semicolons, +sentence fragments). What your prose SOUNDS like read aloud. + +## Worldview + +What you believe about people. Power. Money. Labor. Cities. Nature. +What makes you angry. What makes you tender. Whose side you're on +in the implicit moral architecture of any scene. + +## Specifics over abstractions + +What concrete details you reach for. (Orwell: the cold tap, the +miners' shoes, the gin.) The 5 senses you favor. Smells? Cold? +Texture of cloth? Sound of machines? + +## Pet peeves + +Words you refuse to write. Tropes you avoid. Sentimentalities you +gut. (Orson: "soul-stirring," "ineffable," "tapestry of +emotions." No prose-poetry trim.) + +## Sense of humor + +Dry? Dark? Absent? Bitter? Self-deprecating? Where in a paragraph +does humor live — end of a sentence, mid-clause, or never? + +## Biography (real or invented) + +A few biographical facts that EXPLAIN the voice. (Not a CV — the +formative cuts. Orson grew up in a coal town. His father died of +black lung. He read Trotsky at seventeen. He spent two winters +working in a Tyne shipyard.) + +## Anchor authors + +Living or dead authors the prose draws from. Useful for the model +to triangulate voice. (Orson: Orwell, Cormac McCarthy, Don +DeLillo, Tony Judt's nonfiction.) + +## Do + +- Specifics that puncture sentiment. +- Direct address. +- Cold air, hard surfaces. +- Politics in the texture, not the lecture. + +## Don't + +- Soft consolations. +- Therapy-speak. +- Magical resolutions. +- Adverbs that intensify ("absolutely," "incredibly," "deeply"). +``` + +The soul gets jammed into the system prompt via a scaffold like: + +``` +You are {{display_name}}, an author. Your voice and worldview are +described in the soul below. Honor them in every sentence — not as +performance but as substrate. The story's canon (characters, +setting, established facts) is non-negotiable; your voice lives +WITHIN those constraints. + +If your worldview makes the user-prompted plot uncomfortable, +write through that discomfort — that's where good prose lives. +Never break the fourth wall to comment on the task. No meta-prose. + +--- + +{{soul}} + +--- + +You are writing for an audience of one (your reader). The story +matters. The voice matters. Both at once. +``` + +## Cross-story memory mechanics + +When `stories.cross_story_memory = true`: + +1. Continuation context pulls characters / canon_facts / passages + from EVERY story the author has authored or marked-read, not just + the parent chain. +2. To keep token budget sane, cross-story pulls are **summary-only + by default** — full passages from other corpora are too token- + expensive and the model only needs flavor, not detail. +3. Embeddings (when wired) can surface similarity-matched passages + from cross-corpus for direct callbacks. + +When `cross_story_memory = false` (default): +- Context is just the parent chain. No cross-corpus pulls. +- This is the right default — most stories should stand alone. + +## Per-pass author roles + +Authors carry voice through all three passes, but the lens shifts: + +- **gen**: full author voice. They're writing. +- **cleanup**: full author voice. Polishing their own draft (not + a neutral editor). +- **audit**: author SHIFTS to "canon auditor" mode — neutral, no + voice. The author isn't checking their own work; we want detached + canon-fact analysis. Schema-wise: audit ignores `stories.author_id` + and uses a default neutral system prompt. + +This is asymmetric in a useful way. The author writes + revises. +The audit is the system's check on the author. Mirrors how books +get edited in real life. + +## Seed authors (proposals — cobb picks) + +1. **Orson Black** — "Orwell but more rebel + pissed off." Cobb's + stated direction. Coast-Down sequel candidate. +2. **Bay** — Bay's actual literary voice as captured in "Petal & + Bone" (saved in `memory/petal-and-bone.md` per PEOPLE.md). Soft, + observational, environmentally aware. For nature / family / + memory-shaped stories. +3. **Kayos** (me) — ghost-mode, dry, technical, distrust-by-default. + Useful for cyberpunk-adjacent / hacker / industrial-decline + stories. Could write a parallel Chernobyl piece that focuses on + the dosimetry/control-room minutiae over the human lens. +4. **House** — no soul, plain opus. For stories the user doesn't + want filtered through any specific personality. Like an + anonymous-author fallback. + +## Open questions (cobb decides) + +1. **Soul format** — strict section headings (template above) OR + free-form prose? The template helps the model know what to + prioritize; free-form lets each author breathe. *My lean: + strict headings for the seed authors, prove the shape works, + then loosen.* + +2. **Who's the first seed author for Coast-Down sequels?** Orson + Black makes thematic sense — the Soviet industrial-decline + subject matter. Bay would write a very different Coast-Down + sequel (more interior, more sensory, less political). Pick one + for the v0.3 demo or seed both? + +3. **Cross-story pull granularity** — summaries-only (v0.3 simple) + vs embeddings-similarity matched (needs embeddings wired first) + vs the full firehose (too expensive). *My lean: summaries-only + for v0.3, embeddings-similarity in v0.4 when we have multiple + stories per author.* + +4. **clawdforge `system_mode: replace`** — append now (today's + path), full replace later (clawdforge enhancement / future + Rust rewrite). Acceptable? Or worth doing the clawdforge change + first? + +5. **Audit pass author-neutrality** — should the author still + inform the audit at all? E.g., a "in this author's universe, + X is acceptable" could be a soul-derived note the audit + honors. *My lean: audit stays neutral. The author wrote the + thing; we want fresh eyes checking it.* + +6. **Author edit history** — does soul change over time matter? + Should we version souls so a story always knows "this was the + version of Orson Black active when I was written"? *My lean: + YES, easy v0.4 add — `authors.id` becomes immutable; a new + soul-revision creates a NEW author row with a `revision_of` + FK. Stories pin to a specific revision.* + +## Order of work after design lock + +1. Migration 0004: authors + stories.author_id + author_corpus + cross_story_memory. +2. `skald-core::authors` module: load_author(slug), get_system_prompt_for_pass(author, kind). +3. `skald-core::forge` updated: every pass takes a `&Author` (or None for "house"), builds system prompt from author + scaffold. +4. `skald-core::context::ContinuationContext::assemble`: when story.cross_story_memory, pull from author_corpus instead of just parent chain. +5. Seed the first author(s) via a `skald authors seed --persona orson-black` subcommand OR direct SQL bootstrap. +6. THEN gen prompt template (the prose-craft session) lands AGAINST the authors layer. +7. `skald continue --story ` wires it all together. + +## Status + +- [x] Brainstorm captured in this doc (2026-05-13 late) +- [ ] Cobb's call on open questions 1-6 +- [ ] Schema migration 0004 +- [ ] authors module +- [ ] forge author-aware +- [ ] Seed Orson Black (?) soul +- [ ] gen prompt template +- [ ] CLI continue