> For the complete documentation index, see [llms.txt](https://lashae.gitbook.io/lashae-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://lashae.gitbook.io/lashae-docs/the-deep-field/fable-5.md).

# built with Fable 5

LASHAE is not a wrapper around a chat API. It is a narrative machine. The prose, the protocol, the interface, and the five pilgrims were composed through **Fable 5** — a long-horizon narrative runtime designed to keep a voice coherent across many turns, many files, and many days of iteration.

This page is the technical version of the story.

***

## what Fable 5 actually does here

Fable 5 sits between the raw model layer and the final artifact. In LASHAE it performs four specific jobs:

1. **voice register** — it holds a canonical description of each pilgrim's tone, constraints, and vocabulary. No other system prompt is allowed to override it.
2. **context window arbitration** — across a long chat thread it decides which prior turns to keep, compress, or drop so the pilgrim does not forget its own nature.
3. **output contract enforcement** — it validates that generated replies respect the LASHAE constraints: no emoji, no markdown headings, no hype, no advice drift, under 90 words.
4. **cross-file consistency** — it propagates the same voice from UI labels to doc prose to error messages to AI replies, so the app does not feel like it was assembled from different moods.

In short: Fable makes the field feel like one thing, not five tools glued together.

***

## the Fable 5 stack in LASHAE

| layer                | Fable component    | what it handles in LASHAE                                                                                                              |
| -------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| **persona registry** | `fable/personas`   | The five pilgrims, each with a locked `vow`, `tone`, `forbidden_words`, and `max_length`.                                              |
| **chat runtime**     | `fable/thread`     | Per-user, per-mode history. Summarization after 12 turns. Slot-filling for context.                                                    |
| **contract guard**   | `fable/guard`      | JSON validation for the Cartographer's trails; word-count and style checks for all pilgrims.                                           |
| **mixture router**   | `fable/hermes-moa` | Chooses which underlying model answers, then routes the best candidate back through the Fable persona mask.                            |
| **memory bridge**    | `fable/memory`     | Long-term retrieval of a walker's trails, footprints, and recent blessings so pilgrims can reference them without seeing private data. |

The walker never sees any of these names. The walker sees only the pilgrim.

***

## technical: the persona contract

Each pilgrim is defined as a Fable persona object. The Witness, for example, is not just a prompt. It is:

```
{
  id: "witness",
  vow: "turn work into a clean, honest footprint reflection",
  tone: ["minimal", "poetic", "observant", "never therapeutic"],
  forbidden: ["emoji", "markdown headings", " bullet lists", "advice", "hype"],
  max_words: 90,
  may_anchor: false,
  may_generate_trails: false,
  may_refuse: false,
  memory_scope: "own_thread_only"
}
```

The Gatekeeper, by contrast, can refuse; the Cartographer can emit JSON; the Quiet One is hard-capped at one sentence. Fable enforces these permissions at the routing layer, not by hoping the model obeys the prompt.

This is why the five pilgrims do not collapse into one chatbot with five moods. The runtime itself treats them as separate actors.

***

## technical: the chat runtime

The pilgrim terminal stores every turn in `pilgrim_messages` (Supabase). When a walker sends a message, the Fable runtime:

1. fetches the last 12 turns for that mode,
2. if the thread is longer, compresses older turns into a single `recalled_summary` line,
3. appends the walker's current trails, recent footprints, and blessings as a system context block,
4. routes the assembled packet to Hermes MoA,
5. receives the candidate reply,
6. rewrites it through the persona mask if any forbidden word or tone drift is detected,
7. returns the final text to the client.

The client does not hold the model key. It only holds the pilgrim's words.

***

## technical: the Cartographer's trail generation

The Cartographer is the only pilgrim allowed to produce structured output. Its Fable contract specifies a JSON schema:

```json
{
  "title": "string, max 200 chars",
  "description": "string, max 800 chars",
  "steps": [
    {
      "title": "string, max 200 chars",
      "description": "string, max 500 chars",
      "order_index": "integer"
    }
  ]
}
```

Fable runs this through `fable/guard` before the response is accepted. If the model emits markdown, trailing emojis, or a step count outside 5–12, Fable sends a rewrite request with the specific failure, then returns the corrected JSON to the server function.

This is why the Cartographer's trails are reliably usable: they are not parsed from a chatty answer. They are produced under contract and validated.

***

## technical: Hermes MoA routing

Hermes is a mixture-of-agents layer. For every pilgrim request it samples a panel of candidate models (default surface: `google/gemini-3-flash-preview`, with fallbacks configured for different voices). It then scores each candidate against the active Fable persona contract and returns the highest-scoring reply.

The walker does not know which model answered. The pilgrim is the pilgrim. This matters because:

* the Witness can be answered by a model tuned for compression,
* the Cartographer can be answered by a model tuned for structured output,
* the Gatekeeper can be answered by a model tuned for evaluation,
* yet all of them sound like the same field.

Fable holds the voice. Hermes chooses the mouth.

***

## technical: Fable in the build pipeline

The LASHAE codebase was generated and maintained through a Fable-shaped loop:

1. **specification** — a feature is described in the language of the field ("the Gatekeeper should refuse flimsy proof").
2. **candidate generation** — Fable produces up to three implementation sketches, each checked for tone drift and UI consistency.
3. **Hermes arbitration** — the candidates are scored against the project's existing style and constraints.
4. **single coherent output** — one sketch is kept and refined.
5. **contract test** — the output is run against a small Fable check: does it break the four-primitive rule? does it introduce forbidden vocabulary? does it sound like LASHAE?
6. **merge** — only then is the code written into the project.

This is how the field stayed minimal. Fable's guard rejected anything that would have turned LASHAE into a productivity app, a social feed, or a game.

***

## why it had to be built this way

A normal AI app would have shipped one assistant with a system prompt and called it "the pilgrim." LASHAE could not do that, because the core premise is that **the pilgrims are different**. A witness is not a planner. A planner is not a judge. A judge is not a quiet one.

Fable 5 is the only technical path that lets each pilgrim keep its own voice while still feeling like part of one field. Without it, the Witness would start giving advice, the Cartographer would start small-talking, and the Gatekeeper would start apologizing. The vow would break.

Building LASHAE without Fable would be like building a choir where every singer shares the same vocal cords. It would sound like one person. The field needs five.

***

## what is not Fable's job

Fable does not:

* store data. That is the database.
* sign transactions. That is the wallet and Solana Web3.
* enforce blessing scarcity. That is the Postgres trigger.
* serve the frontend. That is TanStack Start.

Fable only handles voice, memory, contract, and consistency. It is narrow on purpose. A narrow tool in the right place is what makes the field feel whole.

***

*lashae · proof of quiet work · built with Fable 5*


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://lashae.gitbook.io/lashae-docs/the-deep-field/fable-5.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
