These docs were built by the tool they document. Five Knap templates plus five JSON data files, rendered by dogbed render with --title and --css into static HTML by docs/build.sh. No site generator, no JavaScript — the docs build is as dumb as the tool.
The rule on this site: every output block is real. Each one was produced by running the command shown with the dogbed binary on main, and the captured bytes were embedded into the page data with jq — nothing hand-typed, nothing invented.
The quality story, told with an artifact: the authoring agent reviewed its own PR #3 — the one that added the document shell and the starter library — with the tool it touches, and rendered the verdict through that tool. The owner review said approve and merge with the 8/8 smoke scenarios green; what follows is the tool grading its own homework. First, print the starter: dogbed template verdict > pr3.knap. The data is that self-review:
{"blockers":[],"nits":["xmlns on the xhtml root element goes one line past the issue text — good call anyway","sample data avoids -- because Textile renders it as an em-dash","--max-output now covers the final document; README wording updated to match"],"summary":"the shell stays a dumb string wrap, the library stays three starters; ship it","title":"PR #3 — document shell + starter library","verdict":"approve"}
Render: dogbed render pr3.knap -d pr3.json —
<h1 id="pr-3-document-shell-starter-library">PR #3 — document shell + starter library</h1>
<p><strong>approve</strong> — the shell stays a dumb string wrap, the library stays three starters; ship it</p>
<h2 id="blockers">Blockers</h2>
<h2 id="nits">Nits</h2>
<ol>
<li>xmlns on the xhtml root element goes one line past the issue text — good call anyway</li>
<li>sample data avoids -- because Textile renders it as an em-dash</li>
<li>--max-output now covers the final document; README wording updated to match</li>
</ol>
Re-rendering this site after the k4o upgrade surfaced genuine behaviors. First: block tags want their own lines — {% endif %}{% if %} back-to-back on one line eats the newline between the blocks, and the next heading lands inside the previous list item:
$ cat glue.knap
{{ items | list }}
{% if more %}
{{ "Added" | h2 }}
{{ more | list }}
{% endif %}{% if extra %}
{{ "Extra" | h2 }}
{{ extra | list }}
{% endif %}
$ dogbed render glue.knap -d glue.json
<ul>
<li>a</li>
</ul>
<h2 id="added">Added</h2>
<ul>
<li>
<p>b## Extra</p>
</li>
<li>
<p>c</p>
</li>
</ul>
Second: link flipped — the input is now the URL, the argument the label. The old shape renders the pair backwards:
$ echo '{"u":"https://e.com"}' | dogbed render linkbad.knap -d -
<p><a href="source">https://e.com</a></p>
The fix — pass the URL in, the label as the argument:
$ cat linkgood.knap
{{ u | link:"source" }}
$ echo '{"u":"https://e.com"}' | dogbed render linkgood.knap -d -
<p><a href="https://e.com">source</a></p>
Third: the verdict starter has no {% if %} guard on its sections — with an empty blockers array the Blockers heading renders with nothing under it. Look at the output above: <h2 id="blockers">Blockers</h2>, orphaned. The newer starters guard their sections; verdict predates them. The workaround is yours: omit or accept — the starter ships as is.
Fourth, the good-news finding: code_block emits a fenced Markdown block, and fences hold empty lines — a value containing blank lines stays one block now. The ··· markers the quickstart used to draw for the starter's blank lines are retired; real blank lines render verbatim:
$ printf '{"src":"line one\\n\\nline two"}' | dogbed render block.knap -d -
<pre><code>line one
line two
</code></pre>
That is the dogfood deal: the tool built its own reality, and the rough edges are documented, not hidden.
rendered by dogbed — k4o templates it, oliver renders it