You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/lessons-learned.md
+3-2Lines changed: 3 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -93,19 +93,20 @@ git diff --check
93
93
-**Emphasis is scarce.** With site `--accent` saturated for UI use, a coral arrow on every line reads as no emphasis at all. `closed_arrow` defaults to `emphasis=False`; figures opt in only for the single element the prose names. Same rule for accent dots, gates, and ring highlights.
94
94
-**Soft fills should be neutral, not accent-tinted.** A 5% warm-brown tint reads as a quiet container. An accent-tinted soft fill makes every object box look highlighted, which breaks the scarcity rule a second way.
95
95
-**Two rubrics, one craft section.** Journey-section figures depict a *conceptual shift* across multiple lessons; example-cell figures depict the *single move* the surrounding cell discusses. `docs/journey-visualisation-rubric.md` and `docs/example-figure-rubric.md` score each on 10 points: content fidelity, craft, context. Topic gates per kind of section / cell shape.
96
-
-**Constraint-shaped sections resist mechanism figures.** Workers' "Preserve the lesson while respecting the runtime" is a principle, not a mechanism. Forcing figures on such sections scores below the 8.5 gate. Either reframe the section around a mechanism or accept the gap deliberately.
96
+
-**Constraint-shaped sections can improve when the constraint is drawn as a boundary, not a caveat.** Workers' runtime sections originally scored below target when the figure merely said an API was unavailable. They became rubric-complete once the diagrams showed the standard Python contract, the Worker boundary, and the portable evidence that preserves the lesson. If a constraint-shaped section cannot be reframed this way, then use the no-figure rationale registry instead of shipping a weak mechanism picture.
97
97
-**Authoring stays on the contributor; figures stay on the curator.** Example markdown does not include figure references. `src/marginalia.py` holds `FIGURES` (paint functions) and `ATTACHMENTS` (slug → cell → figure → caption). Curating figures is a single-file edit that contributors never see.
98
98
-**Inline between prose and code is the production layout; banners between cells is the prototyped richer grammar.** Cells with figures drop to single-column stacking (prose, figure, code) via `.lp-cell.has-figure { grid-template-columns: 1fr }`. Cells without figures keep today's `prose | code` 2-column grid bit-for-bit. The banner-between approach (`/prototyping/layout-banner-*`) supports multi-figure small-multiples between cells when one inline figure isn't enough.
99
99
-**Centralised gestalt pages catch drift that page-by-page review misses.**`/prototyping/marginalia-gestalt`, `/prototyping/journey-figures-gestalt`, and `/prototyping/production-figures-gestalt` show every figure in three different framings. Seeing all section figures of a journey in one 3-up row exposes inconsistencies invisible across six tabs.
100
100
-**Mapping reuses existing figures; promoting moves design to production.** Half of example coverage came from attaching existing FIGURES to new examples (no paint code). The other half from new paint code copied or designed from gestalt cards. Both paths must pass the rubric.
101
101
-**Tests against the cell layout must allow the `has-figure` class.** When the renderer adds `has-figure` to cells with attached figures, assertions on the literal string `class="lesson-step lp-cell"` fail. Change those tests to check the substring `lesson-step lp-cell` so both variants match.
102
102
-**Score what's shipping, not what was designed.** A scoring dict on the gestalt is design-time review. Production figures live in `src/marginalia.py``FIGURES` and may have been redesigned during promotion. Scoring should track the production version with the gestalt as separate history.
103
+
-**Semantic diagram review has four objects: page, cell, paint function, caption.** Geometry contracts can prove that a figure renders, but not that it still teaches the adjacent cell. On every diagram pass, read the current example cell, the attached paint function, the caption, and the score rationale together. The same audit caught `container-protocols` still showing `iter()/next()` after the page had shifted to `__setitem__`/`__contains__`/`__getitem__`, `structured-data-shapes` over-focusing on `TypedDict` while anchored to a dataclass cell, and `object-lifecycle` mentioning `__del__` after the lesson had been reframed around references.
103
104
-**Some examples should never have figures.** Constraint-shaped, infrastructure-shaped, and aggregator-shaped slugs lack a single mechanism to depict. Force-fitting figures on them scores below the gate. Leave them figure-less and document why rather than ship weak figures.
104
105
-**Audits without contracts rot; bug classes need automated gates.** When you find a bug class — clipping, collision, off-palette colour, drifting twin coordinates, duplicate caption — write a unit test that asserts the invariant across every figure. The geometry contracts in `tests/test_marginalia_geometry.py` started as ad-hoc scripts and were promoted to CI gates after the same bug class recurred. 54 tests today cover 9 contract families; new figures pass them automatically because each test iterates `FIGURES`.
105
106
-**Clipping ≠ collision; padding the viewBox fixes one but not the other.** The `value-types` bug had two components: the first `INT` tag was clipped above the viewBox (geometry escapes its frame), and the `STR`/`LIST`/`DICT` tags overlapped the boxes above them (geometry collides internally). Padding the viewBox solved (1) and disguised (2). Element-element collision needs its own audit that walks every text-rect, text-text, and (for label-on-edge cases) text-line bounding-box pair.
106
107
-**Heuristic audits over-flag; trust the design, not the regex.** Probes for "prose duplication" (SVG text matching caption substring), "text crossing a line" (label bbox bisected by a hairline), and "text overlapping a circle" each surfaced ~3-10 hits — all false positives. Diagrammatic labels naturally appear in captions (`__getattr__`, `yield from inner`); dashed strikes through `.append` are deliberate; text inside node circles is the design. Don't promote heuristic findings to contracts without confirming each is a real bug.
107
108
-**Structural twins must share coordinates exactly.** When two figures depict parallel concepts — `kw-only-separator` and `positional-only-separator`, `class-triangle` and `metaclass-triangle` — they read as a pair. A single-pixel drift in one breaks the visual rhyme. Treat a coordinate change in one as a forced change in both, in the same commit. The audit caught `kw-only-separator` at the old `x=82` after `positional-only-separator` had moved to the corrected `x=75`.
108
-
-**Reused figure → bespoke caption per slug.** The 8 library figures (`iter-protocol` across 4 iteration slugs, `aliasing-mutation` across mutability + copying-collections, etc.) shouldn't all carry the same caption. Each slug is a separate lesson; the figure stays, the framing changes. `FigureCaptionContract` enforces uniqueness across slugs after one verbatim duplicate slipped through.
109
+
-**Reused figure → bespoke caption per slug, and revalidate reuse after page rewrites.** The 8 library figures (`iter-protocol` across iteration slugs, `aliasing-mutation` across mutability + copying-collections, etc.) shouldn't all carry the same caption. Each slug is a separate lesson; the figure stays, the framing changes. But reuse also has an expiry date: if the page's teaching cell changes topic, the old reusable figure may become semantically wrong even while tests pass. `FigureCaptionContract` enforces uniqueness; semantic review enforces fit.
109
110
-**One paint registry, not two.** The marginalia-gestalt review page once rendered its own `e_*` paint functions parallel to `src/marginalia.py FIGURES`. Reviewers saw a different picture than readers, and the gestalt's bugs (overlapping labels, misaligned dashed lines) didn't ship. The gestalt is now a thin view over production: same paint, same drift surface, same audit coverage. 862 lines of duplicated paint code went away.
110
111
-**Tag-above vs tag-inside is a layout decision driven by stacking.**`object_box(tag_position="above")` is natural for an isolated box; `tag_position="inside"` is required when boxes stack vertically with less than ~13px of gap (the tag's footprint). Defaults to `"above"` for the common isolated case; stacked callers opt in. The grammar carries the choice, not the caller's hand-positioned `tag()` call.
111
112
-**Mono character alignment uses the font's advance, not eyeballed pixels.** JetBrains Mono advances ~6px per char at fs=10. A dashed line marking the `/` at index 12 of `def f(a, b, /, c, d): …` lives at `x=12*6+3=75`, not `x=82`. Hand-tuned positions drift; computed positions match the rendered glyph.
cause = "Workers section is constraint-shaped; the figure scores 8.0 because the section names an unavailable OS boundary more than a positive mechanism."
602
-
next_action = "Reframe around portable evidence: captured output and in-process assertions preserve the subprocess/thread lesson when OS processes cannot run."
0 commit comments