Repository navigation
Let the planner reach for a diagram or a formula - #7
Merged
Merged
Conversation
Both already worked. Math is in the dialect's node list with a Lexical node behind it and KaTeX in front, a `mermaid` fence draws an SVG, and the slash menu offers a human either one in a keystroke. The agent, which writes most of the plan, got the bare word "math" in a list of node names and no delimiters at all. Guessing wrong costs nothing visible, which is what makes it worth an instruction rather than a footnote. `\(r = n/t\)` is not rejected — it parses as prose, and markdown eats the backslashes on the way out, so it is saved as `(r = n/t)` and reads like a sentence somebody meant to write. `\[…\]` survives half-escaped, which is no better for being different. The paragraph they were named in is the allowlist, so naming them there said only that they would not be refused. Callout and Tabs each get a clause on when they earn their place; a diagram and a formula had none, under a standing instruction that prose is the default. They have one now, placed before the components so that damper still reads as being about components. The counter-example is written `\\(` in the source. A template literal turns `\(` into `(`, so the obvious spelling would have produced an instruction about parentheses — silently, and in a prompt that nothing tests. The markdown half of that section is still hand-written prose restating `NODES`, `LINK_PROTOCOLS` and `IMAGE_PROTOCOLS`, with nothing tying it to them. It is now the only part of the dialect description that can drift without anything noticing.
This was referenced Oct 10, 2026
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.
Both already worked end to end.
mathandinlineMathare in the dialect's node allowlist with aMathNodebehind them and KaTeX rendering in front, amermaidfence renders to SVG, and the slash menu offers a human either one in a keystroke. The agent — which writes most of the plan — was given the bare word "math" inside a list of node names, with no delimiters anywhere.Why it needed saying
Guessing the wrong delimiters produces no error of any kind:
$r = n / t$inlineMath$r = n / t$$$\nt = n / r\n$$math\(r = n / t\)text(r = n / t)\[t = n / r\]text\[t = n / r]\(…\)is the more common LaTeX convention and so the likelier guess. It is not rejected — it parses as ordinary prose, and markdown eats the backslashes on the way out, so it lands in the plan as(r = n/t)and reads like a sentence somebody meant to write. Nothing anywhere would surface it.\[…\]survives half-escaped, which is no better for being different.The other half is framing. That paragraph is the allowlist, so naming a construct in it says only that it will not be refused. Callout and Tabs each get a clause on when they earn their place; a diagram and a formula had none, under a standing instruction that prose is the default. The new paragraph sits before the components, so that damper still reads as being about components.
The escaping
The counter-example is written
\\(…\\)in the source. A template literal turns\(into(, so the obvious spelling would have shipped an instruction about parentheses — silently, in a prompt that nothing tests. Verified by printingplanner.promptand reading the rendered output rather than the source, which is the only check that means anything here.Checks
bun run ci,bun run typesandbun test(500 pass) are clean. Nothing in this change is behaviour and there is noplanner.test.tsto extend, so no test was added.Left undone
The markdown half of that section is still hand-written prose restating
NODES,LINK_PROTOCOLSandIMAGE_PROTOCOLS, with nothing tying it to them. This does not widen the gap, but it does leave that as the only part of the dialect description able to drift without anything noticing — and the first draft of this very change asserted that\(…\)lands as literal backslashes, which is false. Running it throughparseandserializeis what caught it.