5.3 KiB
5.3 KiB
type, entry_prefix, schema, rules
| type | entry_prefix | schema | rules | |||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| learnings_registry | LRN |
|
|
Learnings registry (LRN)
Index
| ID | Date | Pattern | Applies to |
|---|---|---|---|
| LRN-001 | 2026-05-15 | certbot --nginx matches server_name, not filename |
nginx + certbot on multi-site VPS |
| LRN-002 | 2026-05-17 | PIL supersample ×8 + Lanczos = clean icon antialiasing | Python stdlib icon generation |
| LRN-003 | 2026-07-05 | Prove CSS cleanup behavior-preserving via before/after PDF render-hash | weasyprint / paged-media PDF projects |
| LRN-004 | 2026-07-06 | Digest-pinned base image = frozen CVE exposure; SAST can't see it | any Dockerfile with pinned FROM |
LRN-001 — certbot --nginx matches server_name, not filename
- Date: 2026-05-15
- Pattern:
certbot install --cert-name X(andcertbot --nginx -d X) locates the target vhost by scanning everyserver_namedirective in active nginx configs. The filename insites-available/is irrelevant. A file namedX.confwithserver_name Y;inside will NOT be picked up for domain X. - Context:
/etc/nginx/sites-available/bchanot.frexisted and was symlinked intosites-enabled/, but its body still containedserver_name autreprojet.fr www.autreprojet.fr;— a copy-paste leftover from a previous project. Certbot returnedCould not automatically find a matching server block for bchanot.fr. - Future application: Before running certbot on a multi-site VPS,
grep -n "server_name" /etc/nginx/sites-enabled/*— confirm the target domain is actually declared inside, not just present in the filename. Same logic applies when troubleshooting "why is nginx serving the wrong site" — match byserver_name, never by filename.
LRN-002 — PIL supersample ×8 + Lanczos = clean small-format icon antialiasing
- Date: 2026-05-17
- Pattern: Render icon at 8× target size via
ImageDraw.rounded_rectangle+ellipseon RGBA canvas, thenImage.resize((target, target), Image.LANCZOS). Output rivalsrsvg-convert/inkscapefor simple geometric shapes. Crisp at 16×16 favicon scale, no visible jaggies. - Context: Generated
favicon-32.png,apple-touch-icon.png(180×180),favicon.ico(multi-size 16/24/32/48) forbchanot.frfrom scratch — norsvg-convert/inkscape/ImageMagickon host. Single PIL script, ~20 lines. - Future application: Any project needing a PNG/ICO icon set with a stdlib-only Python toolchain. Skip if shape is complex (text rendering, gradients, curves) — use
rsvg-convertor commit a finalized PNG instead.
LRN-003 — Prove CSS cleanup is behavior-preserving via before/after PDF render-hash
- Date: 2026-07-05
- Pattern: To confirm a CSS/HTML edit is truly behavior-preserving on a project whose deliverable is a weasyprint PDF: render a baseline PDF from the pre-edit HTML, apply the edit, regenerate, then compare (a)
pdftotext | sha256and (b) per-pagepdftoppm -r 150 -png | sha256. Text-hash alone missesfont-size/color changes — the render-hash catches them. Identical render-hash = provably no visual change; and since weasyprint output is deterministic, an unchanged render yields a byte-identical PDF → nothing new to commit. - Context: tour clean phase on
bchanot-cvremoved dead CSS (.reveal.d6,position:running(), no-opbox-shadow, dead.skills-grid font-size). Render-hash matched on both pages → proven before commit30b0e44. The same tooling later confirmed the intentional palette edit DID change the render (expected), distinguishing dead-code removal from real visual change. - Future application: Any weasyprint / paged-media project where you must tell "dead code removal" (must render identically) apart from "intended visual change". General trick: verify a refactor by hashing the rendered artifact, not the source.
LRN-004 — Digest-pinned base image = frozen CVE exposure; SAST can't see it
- Date: 2026-07-06
- Pattern: Digest pin freezes image bytes → also freezes vulnerabilities. Pin correct at audit time can be HIGH same day: upstream retires stable branch, security batch lands only on newer branches, no backport. semgrep/SAST floor scans code, blind to base-image CVE freshness. Complementary posture pass required: base branch EOL status (endoflife.date) + vendor security advisories, every audit.
- Context: bchanot-cv tour 2026-07-05-3.
nginx-unprivileged:1.28-alpinedigest-pinned as SEC fix in morning run; same evening cso posture add-on flagged HIGH — 1.28 branch retired, CVE-2026-42945 (rewrite-module overflow) fixed 1.30.1+/1.31.1+ only. Two intervening semgrep-only tours saw nothing (gstack OFF → no cso). Bump commit1aa97f0. - Future application: Any Dockerfile
FROM x@sha256:…→ security audit must include EOL + advisory check on the pinned branch, not just SAST. gstack ON → cso add-on covers it; OFF → manual endoflife.date + vendor advisory check.