Skip to content

docs: say what the engine is on the first screen, and where it came from - #11

Merged
inhuman merged 4 commits into
mainfrom
docs-positioning
Aug 7, 2026
Merged

docs: say what the engine is on the first screen, and where it came from#11
inhuman merged 4 commits into
mainfrom
docs-positioning

Conversation

@inhuman

@inhuman inhuman commented Aug 7, 2026

Copy link
Copy Markdown
Owner

Nothing in the engine changes here. What changes is whether a reader can tell
what the engine IS before deciding to close the tab.

What was wrong

The README opened with a mechanism and never answered "what is it". A reader
arriving cold had to assemble the answer out of six paragraphs, and the word
"skill" pointed them at the vendor feature of the same name — a folder of
instructions handed to a model — which is close to the opposite of what runs
here. The comparison section named two neighbours and left out the one people
ask about most.

And the provenance was wrong in a way that mattered: both files said the engine
was taken out of a working assistant and ran ~30 skills in production, which
reads as one story and is two.

The first screen

A sentence, then the numbers, then what it deliberately does not do:

A deterministic runtime for one turn of an LLM agent. The model decides
what; the code decides what runs next. A restriction written into a prompt
is a request; a branch that does not exist cannot be taken.

Three sections follow it. What it is — what a skill, the engine and the
application each own, plus a paragraph on the name for readers who arrive with
the other meaning of the word. In 30 seconds — the same turn end to end:
the YAML, six lines of Go, and a real trace from examples/simple-llm-app
rather than a claim about one. Architecture — the picture below.

The picture

The diagram was ASCII art: it wrapped on a phone, read as a code sample, and
could show which side of a boundary a thing was on only by indentation. It is
now an SVG in a <picture> that follows the reader's theme, with the ownership
boundary drawn — the application's frame around everything, the engine as the
one block inside it, five named ports leading back out, and the return path for
what comes back.

Four files, because a picture with words in it has a language. They are
generated by assets/architecture.py, and two guards keep them honest:

  • readme_test.go compares them with each other — two themes of one
    language may differ only in their palette, and the two languages must draw
    the same number of boxes, lines and captions. It found a defect while being
    written: Runner carried two lines of caption in Russian against one in
    English;
  • four files edited by hand in the same wrong way would still agree with each
    other, so CI regenerates them and fails on any difference.

The link check now follows src and srcset too: a theme-specific image is
HTML rather than markdown, and a missing one shows as a broken icon to exactly
half the readers — the half whose theme nobody tested in.

Where it fits

"What this is not" became a table where every neighbour is named with what it
does better, then the architectural reason this is not that: LangGraph,
Temporal, n8n and Airflow, BPMN engines, and MCP. MCP was missing entirely and
is the comparison asked for most; the answer is that it is orthogonal — MCP
says how a call is made, this says which call happens and when — and saying so
is more useful than a list of differences.

Where it came from

Status now carries two facts as two paragraphs. It was written for a home agent
on a single 8 GB GPU, where a generation costs minutes somebody sits
through and the token budget is the card rather than an invoice — which is the
constraint that gave the format its shape. It was adopted by an assistant in
production afterwards, and that is where the catalogue and the measurement come
from.

The order matters beyond accuracy: told the other way round, the same design
looks like an architecture chosen for its own sake.

Also

Everything below the documentation map is now marked as reference, with an
index, because the file is long and a first reader should be able to stop.

Stale numbers, fixed in passing: library v0.5.xv0.8.x, format 2.2.2
2.2.4, coverage 89.3/95.190.1/95.2, and the linter's rule count 29
30 in both READMEs and both quickstarts.

Checks

Vet, Test, Race, govulncheck and Examples as usual, plus the new Diagrams step.
That one was verified by reintroducing the defect: an SVG edited by hand and
staged makes the step fail, and regenerating makes it pass.

inhuman added 4 commits August 7, 2026 01:05
…eighbours

The README opened with a mechanism and never answered "what is it". A reader
arriving cold had to assemble the answer from six paragraphs, and the word
"skill" pointed them at the vendor feature of the same name — a bundle handed
to a model — which is the opposite of what runs here.

So the first screen now carries the sentence itself (a deterministic runtime
for one agent turn), the numbers it produced, and the things it deliberately
does not do. Three sections follow it: what a skill and the engine actually
are, the same turn end to end in thirty seconds (a real trace, not a claim),
and an architecture picture with the ownership boundary drawn on it — the
boundary that zero dependencies is a consequence of, rather than a pose.

"What this is not" became "Where it fits": a table where every neighbour is
named with what it does BETTER — LangGraph, Temporal, n8n, BPMN engines, MCP —
and the architectural reason this is not that. MCP was missing entirely and is
the comparison asked for most often; it is orthogonal, and saying so is more
useful than a list of differences.

Everything below the map is now marked as reference, with an index, because the
file is long and a first reader should be able to stop.

In passing, the numbers that had gone stale: library v0.5.x -> v0.8.x, format
2.2.2 -> 2.2.4, coverage 89.3/95.1 -> 90.1/95.2, and the linter's rule count
29 -> 30 in both READMEs and both quickstarts.
…racters

The picture is the one thing in the README a reader looks at before deciding
whether to read the rest, and it was ASCII art: it wrapped on a phone, it read
as a code sample rather than a diagram, and it could not show which side of the
boundary a thing was on except by indentation.

Now it is an SVG, in a <picture> that follows the reader's theme, with the
ownership boundary drawn: the application's dashed frame around everything, the
engine as the one block inside it, five named ports leading back out to what
the application owns, and the return path along the left for what comes back.

Four files, because a picture with words in it has a language: en and ru, light
and dark. They are generated from assets/architecture.py — one layout, one
string table per language, one palette per theme — so edit that rather than the
SVGs: four pictures kept in step by hand is four chances to leave somebody
looking at a version of the engine that no longer exists.

The generator is a development tool and imports nothing the library ships; the
no-dependency rule is untouched.
The four SVGs are the first thing a reader looks at, and until now nothing
checked them. Two guards, because they catch different failures.

readme_test.go compares the files WITH EACH OTHER: two themes of one language
may differ only in their palette, and the two languages must draw the same
number of boxes, lines and captions — the words differ, the drawing does not.
That is what catches the Russian picture quietly losing a box. It found one
while being written: `Runner` carried two lines of caption in Russian against
one in English. The link check now follows `src` and `srcset` as well, since a
theme-specific image is HTML rather than markdown, and a missing one shows as a
broken icon to exactly half the readers — the half whose theme nobody tested in.

Four files edited by hand in the same wrong way would still agree with each
other, so CI regenerates them and fails on any difference. That is the guard
against an SVG edited directly instead of through assets/architecture.py, and
against a generator whose output nobody re-ran.
Both READMEs said the engine was taken out of a working assistant and ran ~30
skills in production, which reads as one story and is two. It was written for a
home agent on a single 8 GB GPU, and only afterwards adopted by an assistant in
production — where the catalogue and the measurement below come from.

The order matters beyond accuracy. On one consumer card a generation costs
seconds somebody sits through, so removing one is not an optimisation but the
condition for the thing being usable at all — which is the constraint that gave
the format its shape. Told the other way round, the same design looks like an
architecture chosen for its own sake.

So Status now carries the two facts as two paragraphs, and the summary row on
the first screen names both.
@inhuman
inhuman merged commit e628fa8 into main Aug 7, 2026
1 check passed
@inhuman
inhuman deleted the docs-positioning branch August 7, 2026 09:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant