From 9a1d33294659dcc6110d66fa183f8c2678f680de Mon Sep 17 00:00:00 2001 From: Boris Dev Date: Tue, 6 Oct 2026 21:24:19 +0000 Subject: [PATCH] README: draw the specification diagram, not only the two-strategy diff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The before/after is the pitch — the same graph with nothing implemented, then with two implementations bound — and only the second half was ever drawn. `diagram()` was described in prose and never shown. The check that should have caught this could not. `test_the_readme_mermaid_block_is_ the_diagram_the_code_emits` asserted ONE block by name, at a time when the README had exactly one: a check narrower than its claim, and blind to a missing picture because the blocks that are present all pass. Replaced with a set match over every mermaid block in every markdown file, in both directions — a block with no generator fails, and a registered generator with no block fails too. Verified both go red. 282 tests green locally. No CI in this repo, so that is one local run. --- README.md | 25 +++++++++++++-- tests/test_greeting.py | 69 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 83 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ede6510..f3f2689 100644 --- a/README.md +++ b/README.md @@ -116,8 +116,27 @@ One workflow — normalize a name, then compose a greeting from it: Desired behaviour: preserve the name's words, trim surrounding whitespace, collapse repeated internal whitespace, return `Hello, {name}!`. -Two strategies disagree about how much of that `normalize` does. `compose` is the same function -in both, so the comparison diagram highlights the one node that varies: +That table is the whole declaration, and it draws itself. **Nothing is implemented at this +point** — no `normalize` body, no `compose` body, no strategy, nothing an agent has written: + +```mermaid +flowchart TD + START([START]) + normalize["normalize"] + compose["compose"] + END([END]) + START -- raw_name --> normalize + normalize -- clean_name --> compose + compose -- greeting --> END +``` + +Bare boxes, because nothing is bound to them yet. This picture and `coherence_check()` are what +you review *before* asking an agent for a line of code — which is the one thing a drawing taken +from a built graph cannot do, since building it requires the code to already exist. + +Two strategies disagree about how much of that `normalize` does. Same graph, two implementations +bound: `compose` is the same function in both, so the comparison greys it and highlights the one +node that varies: ```mermaid flowchart TD @@ -194,7 +213,7 @@ Everything it produces goes to the terminal; no files are written. Excerpt: normalize_spaces 1.00 ``` -Two mermaid blocks go past on the way: the specification, and the comparison above. A browser +Both mermaid blocks above go past on the way — the specification, then the comparison. A browser viewer is available as a separate process — `uv run python3 -m workflow_workbench.cli serve`, see [`serve.py`](workflow_workbench/serve.py) — and nothing in the quickstart needs it. diff --git a/tests/test_greeting.py b/tests/test_greeting.py index 2661bea..dbee41f 100644 --- a/tests/test_greeting.py +++ b/tests/test_greeting.py @@ -104,17 +104,70 @@ def _score(report) -> float: return float(getattr(v, "value", v)) -def test_the_readme_mermaid_block_is_the_diagram_the_code_emits() -> None: - """⛔ THE ONE THAT MATTERS MOST. A hand-pasted diagram is a claim about the declaration that - stops being true the moment a node is renamed, and nothing else would notice. +# ── every drawn diagram, in BOTH directions ────────────────────────────────────────────────── +# +# ⛔ The check this replaced asserted ONE block — `diff_diagram()` — by name, at a time when the +# README contained exactly one. That is the repo's recurring defect: a check narrower than its +# claim, which goes quiet the moment a second block is pasted in by hand. So the registry below +# is matched against the docs as a SET, and a block with no entry fails just as loudly as an +# entry with no block. + +def _drawn() -> dict[str, str]: + """Every mermaid body the docs are expected to show, keyed by how to regenerate it. The `%%` title line is dropped because a fenced mermaid block on GitHub does not need it. """ - drawn = Greeting().diff_diagram(trim_only, normalize_spaces) - body = "\n".join(ln for ln in drawn.splitlines() if not ln.startswith("%%")).strip() - assert f"```mermaid\n{body}\n```" in README, ( - "the README's mermaid block is not what diff_diagram() emits. Regenerate it:\n" - " uv run python3 -m examples.greeting") + spec = Greeting() + return { + "Greeting().diagram()": spec.diagram(), + "Greeting().diff_diagram(trim_only, normalize_spaces)": + spec.diff_diagram(trim_only, normalize_spaces), + } + + +def _fenced(body: str) -> str: + return "```mermaid\n" + "\n".join( + ln for ln in body.splitlines() if not ln.startswith("%%")).strip() + "\n```" + + +def _blocks_in_markdown() -> dict[str, list[str]]: + """⚠️ Every markdown file, not just the README. A hand-pasted diagram in `docs/` is the same + claim about the declaration and rots the same way.""" + found: dict[str, list[str]] = {} + for path in sorted(ROOT.rglob("*.md")): + if any(part in {".venv", "node_modules", ".git"} for part in path.parts): + continue + text = path.read_text() + hits = [f"```mermaid\n{chunk.split('```')[0].strip()}\n```" + for chunk in text.split("```mermaid\n")[1:]] + if hits: + found[str(path.relative_to(ROOT))] = hits + return found + + +def test_every_mermaid_block_in_the_docs_is_one_the_code_emits() -> None: + """⛔ THE ONE THAT MATTERS MOST. A hand-pasted diagram is a claim about the declaration that + stops being true the moment a node is renamed, and nothing else would notice.""" + expected = {_fenced(body): how for how, body in _drawn().items()} + for path, blocks in _blocks_in_markdown().items(): + for block in blocks: + assert block in expected, ( + f"{path} contains a mermaid block no generator emits. Either regenerate it " + f"(uv run python3 -m examples.greeting) or register its source in _drawn().\n" + f"{block}") + + +def test_every_diagram_the_code_emits_is_actually_drawn_in_the_docs() -> None: + """The other direction, and the reason the plain `diagram()` block exists at all. + + `diagram()` — the picture with NOTHING implemented — was described in prose for weeks and + never drawn, while only the two-strategy diff was shown. A one-directional check cannot see + a missing picture: the blocks that are present all pass. + """ + drawn_anywhere = {b for blocks in _blocks_in_markdown().values() for b in blocks} + for how, body in _drawn().items(): + assert _fenced(body) in drawn_anywhere, ( + f"{how} is registered as a diagram the docs show, and no markdown file shows it.") @pytest.mark.parametrize("case,text,expected", CASES)