lowest-common-denominator-output
<!-- SPDX-License-Identifier: CC-BY-SA-4.0 --> ## Learning Record **Project codename:** blue-marlin **Date:** 2026-04-26 **Category:** gap **Severity:** significant **Framework version:** 0.34.0 ### What happened The project generates DXF drawings as one of its outputs (alongside STEP / GLB / CSV). After iterating to add DXF dimensions and labels, the user (Governor-Reviewer) opened the files in a 3D-CAD viewer (Onshape-style) and reported that **the dimensions were not visible**, despite the entity count showing the expected 4-7 DIMENSION entities per file. Diagnosis: 3D-CAD tools (Onshape, Fusion 360, SolidWorks DXF import, FreeCAD Part workbench) typically import DXF as sketch geometry only and silently skip DIMENSION blocks — these are annotation entities, not sketch geometry. Drawing-focused tools (LibreCAD, AutoCAD, FreeCAD Draft, Inkscape with DXF plugin) do render DIMENSION blocks correctly. The format technically supported the dimensions; the chosen viewer ecosystem did not. The fix replaced `ezdxf.add_linear_dim()` (which produces DIMENSION blocks) with manual LINE drawing for the dimension geometry — extension lines + dim line + arrowhead lines as plain LINE entities, plus `add_text` for the mm value. Each dimension is now 7 LINE entities + 1 TEXT entity instead of 1 DIMENSION + INSERT block. The pattern repeated one layer deeper: after the LINE-based dimension fix, the user reported dimensions visible BUT the actual mm numbers still missing. Same root cause: the viewer also ignores DXF TEXT entities when their font reference (Standard / `txt.shx`) is unavailable. Same fix pattern — replace TEXT with LWPOLYLINE outlines via `ezdxf.addons.text2path` which converts each character to outline paths. Final output: zero TEXT, zero DIMENSION, zero font dependencies. Every visible mark in the DXF is now LINE, LWPOLYLINE, or CIRCLE. This took **two iterations of user feedback** to resolve fully — once for DIMENSION blocks, once for TEXT entities. Both could have been addressed in one iteration if the principle had been applied exhaustively to the entire format usage tree on the first pass. ### Agents involved coder-tester, governor-reviewer ### Framework section `framework.md` (no specific section currently); `rules-template/workflow/tdd-rule.md` (related); new candidate: file-generator rule. ### Business impact `prevented_loss` — dimensions now visible in the user's actual viewer ecosystem. The iteration that produced the DIMENSION-block output passed every automated check (entity counts correct, file sizes plausible, validators clean), but the deliverable was unusable in the user's chosen tool. Without the user's visual review, the project would have shipped invisible dimensions. ### Recommendation Add a new framework principle / rule: > **Lowest-common-denominator output principle.** When generating > files for unknown or heterogeneous viewer ecosystems, prefer the > most universally-rendered primitives over advanced format features, > even at the cost of more verbose code or larger file size. > > Apply EXHAUSTIVELY in one pass — audit every branch of the format > usage tree (entity types, blocks, font references, layer features, > encoding) and downgrade EACH branch to the most basic equivalent. > Iterating per defect class wastes user-feedback rounds (this > project took two rounds: DIMENSION → LINE+TEXT, then TEXT → > LWPOLYLINE). Concrete examples (DXF case from this project): | Format feature | Universal alternative | Trade-off | |---|---|---| | `DIMENSION` blocks | LINE + LINE arrowheads + TEXT/polyline | 7-8x more entities per dim | | `TEXT` entities | LWPOLYLINE glyph outlines (via `text2path`) | ~10x more entities per character; rough Hershey-style fonts | | `MTEXT` / formatted text | Plain TEXT or LWPOLYLINE | No formatting | | `HATCH` fills | LWPOLYLINE outline + maybe stipple lines | No fills | | Layered visibility | Single layer + line-weight differentiation | Loss of toggle-ability | The principle generalises to other formats: - SVG: prefer `<line>`, `<polyline>`, `<rect>` over `<filter>`, `<animate>`, `<feFlood>` if target audience uses heterogeneous viewers. - PDF: PDF/A subset over full-feature PDF for archive/exchange. - CSV: avoid Excel-specific quirks (BOM, formula cells); plain comma-separated UTF-8. - JSON-LD: limit to JSON-LD 1.0 features if consumers may not support 1.1. Suggested addition to `rules-template/workflow/`: a new `file-generator-rule.md` capturing this principle plus the audit checklist (entity types, blocks, font references, layer features, encoding). Suggested addition to `framework.md` or `ADOPTING.md`: a short reference to this principle in the context of any task that produces files consumed by third-party tools. --- **Anonymization checklist:** - [x] No real project, product, or organisation names - [x] No internal URLs, hostnames, or infrastructure identifiers - [x] No customer or partner names
issue