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
Designed figures for the last 19 examples that previously lacked a
figure — all the constraint-shaped / infrastructure / advanced-typing
slugs. Each got a tightened mechanism picture against the
example-figure rubric:
package-tree packages
venv-boundary virtual-environments
subprocess-spawn subprocesses
logging-levels logging
aaa-pattern testing
protocol-layers networking
gil-lanes threads-and-processes
cast-escape casts-and-any
newtype-phantom newtype
overload-signatures overloads
paramspec-preserve paramspec
literal-constrained literal-and-final
callable-type callable-types
isinstance-check runtime-type-checks
collections-containers collections-module
typed-dict-shape structured-data-shapes
csv-records csv-data
warning-signal warnings
object-lifecycle object-lifecycle
These cells had been flagged "constraint-shaped, may not need figures";
revisiting found that most of them DO have a single mechanism worth
depicting (a tree, a boundary, a spawn arrow, a stack of layers, an
arrange-act-assert sequence). The two genuine principles in the set
(casts-and-any, newtype) got figures depicting the static/runtime gap
they exploit.
docs/lessons-learned.md gains a new "Visualisations and marginalia"
section: 15 lessons from this thread including the grammar rule,
SVG-sizing pipeline invariants, prose-vs-figcaption discipline,
emphasis scarcity, the two-rubric structure, constraint-shaped section
limits, contributor vs curator split, inline-between vs banner grammars,
centralised gestalt-page pattern, mapping-vs-promotion paths, the
test-class-string fix, scoring discipline, and the explicit "some
examples should never have figures" rule.
Final coverage:
Examples: 109/109 attached (100%)
Journeys: 24/24 section figures (100%)
FIGURES: 103 registered
39 unit tests pass
https://claude.ai/code/session_01MazwoRWAihW6dwso3fMCHE
Copy file name to clipboardExpand all lines: docs/lessons-learned.md
+17Lines changed: 17 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -84,3 +84,20 @@ git diff --check
84
84
- Keep `README.md` focused on how to understand, verify, and deploy the project.
85
85
- Keep this lessons document updated when a bug reveals a general rule.
86
86
- Record user-visible changes in `CHANGELOG.md` before significant commits or releases.
87
+
88
+
## Visualisations and marginalia
89
+
90
+
-**A diagram set needs a grammar, not a collection of one-off layouts.** Hand-drawn SVGs drift in stroke weight, cell size, type-tag placement, arrow style. A locked `Canvas` grammar (palette, tokens, words, phrases, metrics) makes drift structurally impossible. Cards declare figures by composing primitives; the library guarantees consistency.
91
+
-**Emit explicit `width`/`height` on every SVG; use `max-width: 100%` in CSS, never `width: 100%`.** Without `width`/`height` the browser stretches a small viewBox to fill its container, doubling text inside. This was the root cause of every "figure too big" report. The fix lives in `Canvas.to_svg()` and the CSS rules in `public/site.css`, `scripts/build_prototypes.py`, and `scripts/build_marginalia.py`.
92
+
-**A figure's diagrammatic content must not duplicate its figcaption.** SVGs may carry functional labels (`stdout`, `iter()`, panel tags like `before` / `after`, type signatures like `x: int | str | None`). Full sentences describing the figure as a whole are prose and belong in the figcaption. Captions are the canonical voice. The exception is review-only pages (`marginalia-gestalt`) where cards have no figcaption; figures destined for promotion to production must drop their inline prose first.
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
+
-**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
+
-**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.
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
+
-**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
+
-**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
+
-**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
+
-**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
+
-**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
+
-**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.
0 commit comments