Skip to content

How it works

WRITING AGENT is a pipeline, not a prompt. A topic goes in; a durable on-disk state machine walks it through a fixed sequence of stages, and each stage is one focused LLM call (a node) with a typed input and output. The interesting part isn’t any single model call - it’s the loop wrapped around every unit of writing, and the memory that survives between them.

The system improves with use by accumulating on-disk memory - craft skills and a watch-list - not by retraining or fine-tuning the model. The model weights never change; what changes is the retrieved memory each agent is given. “Learning” here means better notes on disk, not a different model.

Every node does exactly one job and routes to its own model tier (Pro for judgment and prose, Flash for volume). By default there is no free-roaming “agent” deciding what to do next - the orchestrator does, deterministically. (Flip on the opt-in agentic controller and a policy chooses each unit’s next move instead.)

AgentJobTier
PlannerProposes 3 directions/angles, then expands the chosen one into a planPro
TOC / OutlineChapter blueprints (book) or section outline (article)Flash
ThesisGenerates the article’s contestable claim + steelmanned counterargumentPro
WriterDrafts a unit - samples divergent variants at different temperaturesPro
CriticApprove / revise / escalate + insight·clarity·structure·evidence scoresPro
JudgePicks the strongest of N divergent drafts, read side by sidePro
VerifierChecks each cited claim against its source text (articles)Pro
HumanizerSurgically rewrites only the sentences with AI tellsFlash
SummarizerPer-unit summary that feeds the next unit’s contextFlash
Canon extractorPulls characters, world rules, and timeline from committed proseFlash
ResearcherShallow brief or deep multi-source synthesis (opt-in)Flash
DiagramAuthors a figure spec (nodes/edges); a layout engine - built-in or D2/ELK - draws itPro
ConsolidationReads the whole canon, merges duplicates, flags contradictionsPro
ProductionDecides and generates front/back matter, assembles the manuscriptFlash
LearnerDistills craft skills + a watch-list; scores skills with ablation duels; enforcement guarded by watch_blockingFlash
ChatThe TUI’s conversational assistantFlash

The orchestrator runs the same shape for both modes - only the unit (chapter vs section) and the book-only passes (canon, consolidation, production) differ.

Article:
topic → 3 angles (pick) → THESIS → outline (default 6 sections)
→ per section: research? → write → critique → revise(×N) → humanize → commit
→ cohesion pass → references → manuscript.md → SEO + promo (auto) → learn
Book:
abstract → 3 directions (pick) → plan + TOC
→ per chapter: research? → write → critique → revise(×N) → humanize
→ commit (+ summary + canon extraction)
→ consolidate (every N chapters) → production (front/back matter) → learn

The unit chain is sequential by design - each unit reads the previous unit’s summary for continuity - while everything independent of prose (research, images, skills for unit n+1, and the humanize/summarize/extract commit batch) runs concurrently.

Two things happen deterministically as prose commits: generated diagrams are reconciled into the manuscript (embedded where they belong), and anything dropped - an unused image, a skipped suggestion - is logged to rejected.jsonl so nothing vanishes silently. It’s reviewable in the web dashboard’s Rejected tab.

A finished article isn’t just exported - it’s prepared to be found and shared. With auto_promote on (default), the pipeline runs an SEO + promotion pass after the manuscript is assembled:

  • SEO - a deterministic on-page audit plus a one-call flash keyword pack; the keyword is threaded into the writer up front and the title is optimized after validation, and the findings are written to seo_report.md.
  • Promotion - platform-native variants (X thread, LinkedIn post, newsletter teaser, TL;DR) plus headline variants, reusing the keyword pack.

Both only produce local artifacts - the SEO pass edits the article and adds keywords/hashtags; the promo pass writes files under promo/. Nothing is ever posted or scheduled anywhere.

Cost is a first-class design constraint. cost_mode is budget by default: it pins the spend-heavy knobs lean, routes the judgment nodes (critic, judge, verifier, consolidation, diagram) to the cheaper flash tier, and applies a per-unit token budget (budget_tokens_per_unit, default 20 000) plus a fixed overhead - targeting ≤100k tokens per article. max_run_tokens is a separate hard ceiling that pauses a run if hit. Switch to standard when quality outranks spend. Every LLM call is attributed per node and per unit, which is what powers the dashboard’s Telemetry and Cost views.

The same engine runs behind two front ends: the interactive TUI (writing-agent) and a local web dashboard (writing-agent web) - a stdlib server that streams a live run over Server-Sent Events and exposes the same runs, evals, artifacts, cost, and settings in a browser, binding 127.0.0.1 only.

This is the heart of the system. Every drafted unit runs through the same loop before it is allowed to commit:

  • Divergent drafts. The first attempt samples N variants at different temperatures (0.7 / 1.0 / 1.2); the critic ranks them and the strongest is refined - selection for boldness, not convergence to the safest median.
  • The critic gates the commit. It returns approve, revise, or escalate, scores insight·clarity·structure·evidence, and treats AI slop and unsupported claims as blocking, not nits.
  • Revise up to a cap. Each revise is a fresh draft + critique, up to max_revisions (default 2). A correct-but-generic draft below the insight bar gets a “sharpen the argument” pass instead of a pass.
  • At the cap, mode decides. In manual mode you get a one-keypress escalation menu; in autonomous mode the best-judged draft is committed and the run never pauses.
  • Humanize is surgical. Only the sentences flagged as AI tells are rewritten - each rewrite guarded so citations, numbers, and length survive. Approved prose is never wholesale regenerated.

See Review, revise & trust and Quality machinery for what each stage enforces.

By default the orchestrator runs the fixed sequence above. Turn on the agentic controller (/agentic on or agentic: true, off by default) and that order becomes a decision: before drafting each unit a policy chooses the next move - draft, gather research, or read canon - and the writer can call research / canon tools mid-draft (in-generation tool use). It’s bounded by per-unit step and token caps, and the fixed pipeline is always the fallback, so off = byte-identical behavior.

The policy is one of three: default (always draft - the fixed pipeline), llm (an LLM controller decides), or trace (a policy learned from your own past runs’ action traces, which abstains until it has enough labelled data). Every decision is logged to agent_trace.jsonl and surfaced by /trace and /agentic. See Settings and plan.md §21.

There is no database server and no in-memory graph that disappears on exit. The brain on disk is the source of truth and the checkpoint. Every step persists - atomically - before the state machine advances:

brain/users/<you>/
books/<id>/ chapters, plan, canon (characters · world rules · timeline), manuscript, exports
articles/<id>/ sections, thesis, sources, manuscript, images
skills/ learned craft skills, promoted by efficacy
voice/ admired passages the writer matches

Because the state lives in plain markdown + JSON, a run can be killed at any point and run resumes exactly where it stopped - resume guards make double-commits impossible. The full module-level picture is in Architecture; unfamiliar terms are defined in the Glossary.