docs: say what the engine is on the first screen, and where it came from - #11
Merged
Conversation
…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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:
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-apprather 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 ownershipboundary 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.gocompares them with each other — two themes of onelanguage 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:
Runnercarried two lines of caption in Russian against one inEnglish;
other, so CI regenerates them and fails on any difference.
The link check now follows
srcandsrcsettoo: a theme-specific image isHTML 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.x→v0.8.x, format2.2.2→2.2.4, coverage89.3/95.1→90.1/95.2, and the linter's rule count29→30in 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.